ClojureScript test coverage report

Total forms hit rate : 978/1214 (80.6%)

Total sub forms hit rate : 26737/36202 (73.9%)

cljs.compiler.api (33%)
cljs.instant (93%)
cljs.source-map.base64-vlq (98%)
cljs.closure (71%)
cljs.analyzer.impl.namespaces (100%)
cljs.compiler-tests (93%)
cljs.js-deps (91%)
cljs.externs (98%)
cljs.tagged-literals (57%)
cljs.test-runner (100%)
cljs.module-processing-tests (100%)
cljs.compiler (83%)
cljs.closure-tests (0%)
cljs.analyzer-tests (100%)
cljs.analyzer (86%)
cljs.util (77%)
cljs.source-map.base64 (87%)
cljs.build.api (20%)
cljs.support (100%)
cljs.build-api-tests (100%)
cljs.reader (100%)
cljs.analyzer-api-tests (100%)
cljs.module-graph (90%)
cljs.module-graph-tests (100%)
cljs.repl (1%)
cljs.source-map (74%)
cljs.test-util (99%)
cljs.analyzer.passes.and-or (100%)
cljs.env (100%)
cljs.analyzer.passes (100%)
cljs.core (77%)
cljs.analyzer.api (41%)
cljs.pprint (81%)
cljs.externs-infer-tests (100%)
cljs.compiler.api 39/115 (33.9%)
(defn with-core-cljs
  "Ensure that core.cljs has been loaded."
  ([]
    (comp/with-core-cljs
      (when-let [state (ana-api/current-state)]
        (:options (clojure.core/deref state)))))
  ([opts] (with-core-cljs opts (fn [])))
  ([opts body]
    (with-core-cljs
      (or (ana-api/current-state) (ana-api/empty-state opts))
      opts
      body))
  ([state opts body]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (comp/with-core-cljs opts body)))))
(defn compile-file
  "Compiles src to a file of the same name, but with a .js extension,\n   in the src file's directory.\n\n   With dest argument, write file to provided location. If the dest\n   argument is a file outside the source tree, missing parent\n   directories will be created. The src file will only be compiled if\n   the dest file has an older modification time.\n\n   Both src and dest may be either a String or a File.\n\n   Returns a map containing {:ns .. :provides .. :requires .. :file ..}.\n   If the file was not compiled returns only {:file ...}"
  ([src] (compile-file src (closure/src-file->target-file src)))
  ([src dest] (compile-file src dest nil))
  ([src dest opts]
    (compile-file
      (or (ana-api/current-state) (ana-api/empty-state opts))
      src
      dest
      opts))
  ([state src dest opts]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (comp/compile-file src dest opts)))))
(defn requires-compilation?
  "Return true if the src file requires compilation."
  ([src dest] (requires-compilation? src dest nil))
  ([src dest opts]
    (requires-compilation?
      (or (ana-api/current-state) (ana-api/empty-state opts))
      src
      dest
      opts))
  ([state src dest opts]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (comp/requires-compilation? src dest opts)))))
(defn munge
  "Munge a symbol or string. Preserves the original type."
  [s]
  (comp/munge s))
(defn compile-root
  "Looks recursively in src-dir for .cljs files and compiles them to\n   .js files. If target-dir is provided, output will go into this\n   directory mirroring the source directory structure. Returns a list\n   of maps containing information about each file which was compiled\n   in dependency order."
  ([src-dir] (compile-root src-dir "out"))
  ([src-dir target-dir] (compile-root src-dir target-dir nil))
  ([src-dir target-dir opts]
    (compile-root
      (or (ana-api/current-state) (ana-api/empty-state opts))
      src-dir
      target-dir
      opts))
  ([state src-dir target-dir opts]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (comp/compile-root src-dir target-dir opts)))))
(defn emit
  "Given an AST node generated by the analyzer emit JavaScript as a string."
  ([ast] (emit (or (ana-api/current-state) (ana-api/empty-state)) ast))
  ([state ast]
    (ana-api/with-state state (with-out-str (comp/emit ast)))))
(defn cljs-files-in
  "Return a sequence of all .cljs and .cljc files in the given directory."
  [dir]
  (comp/cljs-files-in dir))
cljs.instant 42/45 (93.3%)
(defn- construct-instant
  "Construct a java.time.Instant, which has nanosecond precision."
  [years
   months
   days
   hours
   minutes
   seconds
   nanoseconds
   offset-sign
   offset-hours
   offset-minutes]
  (Instant/from
    (OffsetDateTime/of
      years
      months
      days
      hours
      minutes
      seconds
      nanoseconds
      (ZoneOffset/ofHoursMinutes
        (* offset-sign offset-hours)
        (* offset-sign offset-minutes)))))
(defmethod
  print-method
  java.time.Instant
  [instant w]
  (print-instant instant w))
(defn- remove-last-char [s] (subs s 0 (dec (count s))))
(defn read-instant-instant
  "To read an instant as a java.time.Instant, bind *data-readers* to a\n  map with this var as the value for the 'inst key. Instant preserves\n  fractional seconds with nanosecond precision. The timezone offset will\n  be used to convert into UTC."
  [cs]
  (inst/parse-timestamp (inst/validated construct-instant) cs))
(defn- print-instant
  "Print a java.time.Instant as RFC3339 timestamp, always in UTC."
  [instant w]
  (.write w "#inst \"")
  (.write w (remove-last-char (.format utc-format instant)))
  (.write w "-00:00\""))
(defmethod
  print-dup
  java.time.Instant
  [instant w]
  (print-instant instant w))
cljs.source-map.base64-vlq 100/102 (98.0%)
(defn bit-shift-right-zero-fill [x n]
  (bit-shift-right (bit-and 4294967295 x) n))
(defn decode [s]
  (let [l (.length s)]
    (loop [i 0 result 0 shift 0]
      (when (>= i l)
        (throw (Error. "Expected more digits in base 64 VLQ value.")))
      (let [digit (base64/decode (.charAt s i))]
        (let [i (inc i)
              continuation? (pos? (bit-and digit vlq-continuation-bit))
              digit (bit-and digit vlq-base-mask)
              result (+ result (bit-shift-left digit shift))
              shift (+ shift vlq-base-shift)]
          (if continuation?
            (recur i result shift)
            (lazy-seq
              (cons
                (from-vlq-signed result)
                (let [s (.substring s i)]
                  (when-not (string/blank? s) (decode s)))))))))))
(defn encode [v] (apply str (map encode-val v)))
(defn from-vlq-signed [v]
  (let [neg? (= (bit-and v 1) 1) shifted (bit-shift-right v 1)]
    (if neg? (- shifted) shifted)))
(defn to-vlq-signed [v]
  (if (neg? v)
    (inc (bit-shift-left (- v) 1))
    (+ (bit-shift-left v 1) 0)))
(defn encode-val [n]
  (let [sb (StringBuilder.) vlq (to-vlq-signed n)]
    (loop [digit (bit-and vlq vlq-base-mask)
           vlq (bit-shift-right-zero-fill vlq vlq-base-shift)]
      (if (pos? vlq)
        (let [digit (bit-or digit vlq-continuation-bit)]
          (.append sb (base64/encode digit))
          (recur
            (bit-and vlq vlq-base-mask)
            (bit-shift-right-zero-fill vlq vlq-base-shift)))
        (.append sb (base64/encode digit))))
    (str sb)))
cljs.closure 3943/5514 (71.5%)
(defn make-preamble [{:keys [target preamble hashbang]}]
  (str
    (when (and (= :nodejs target) (not (false? hashbang)))
      (str "#!" (or hashbang "/usr/bin/env node") "\n"))
    (when preamble (preamble-from-paths preamble))))
(defn closure-transpile
  "Transpile a single JavaScript file to JavaScript. Used to lower Closure\n  Library files written in more recent versions of the JavaScript standard."
  ([rsc opts] (closure-transpile (util/path rsc) (slurp rsc) opts))
  ([path source opts]
    (let [cc (make-closure-compiler)
          cc-opts (set-options opts (transpile-options))
          externs (SourceFile/fromCode
                    "externs.js"
                    "function Symbol() {}")
          source (SourceFile/fromCode path source)
          result (.compile cc externs source cc-opts)]
      (.toSource cc))))
(defn resolve-warning-handlers [fns]
  (reduce
    (fn [ret afn]
      (cond
        (fn? afn) (conj ret afn)
        (symbol? afn) (let [afn' (sym->var afn :warning-handlers)]
                        (when-not afn'
                          (throw
                            (ex-info
                              (str
                                "Could not resolve warning handler: "
                                afn)
                              {:warning-handlers fns 
                               :clojure.error/phase :compilation})))
                        (conj ret afn'))
        :else (throw
                (ex-info
                  (str
                    "Invalid warning handler "
                    afn
                    " of type "
                    (type afn))
                  {:warning-handlers fns 
                   :clojure.error/phase :compilation}))))
    []
    fns))
(defn lang-key->lang-mode [key]
  (case
    (expand-lang-key key)
    :no-transpile
    CompilerOptions$LanguageMode/NO_TRANSPILE
    :ecmascript3
    CompilerOptions$LanguageMode/ECMASCRIPT3
    :ecmascript5
    CompilerOptions$LanguageMode/ECMASCRIPT5
    :ecmascript5-strict
    CompilerOptions$LanguageMode/ECMASCRIPT5_STRICT
    :ecmascript6
    CompilerOptions$LanguageMode/ECMASCRIPT_2015
    :ecmascript6-strict
    CompilerOptions$LanguageMode/ECMASCRIPT_2015
    :ecmascript-2015
    CompilerOptions$LanguageMode/ECMASCRIPT_2015
    :ecmascript-2016
    CompilerOptions$LanguageMode/ECMASCRIPT_2016
    :ecmascript-2017
    CompilerOptions$LanguageMode/ECMASCRIPT_2017
    :ecmascript-next
    CompilerOptions$LanguageMode/ECMASCRIPT_NEXT))
(defn- constants-javascript-file
  "Returns the constants table as a JavaScriptFile."
  [opts]
  (let [url (deps/to-url (constants-filename opts))]
    (javascript-file
      nil
      url
      [(str ana/constants-ns-sym)]
      ["cljs.core"])))
(defn get-source-files [js-modules opts]
  (map
    (fn [lib]
      (let [file (if-let [file-min (and
                                     (#{:simple :advanced}
                                       (:optimizations opts))
                                     (:file-min lib))]
                   file-min
                   (:file lib))]
        (js-source-file file (deps/-source lib))))
    js-modules))
(defn add-js-sources
  "Given list of IJavaScript objects, add foreign-deps, constants-table\n   IJavaScript objects to the list."
  [inputs opts]
  (let [requires (set (mapcat deps/-requires inputs))
        required-js (js-dependencies opts requires)]
    (concat
      (map
        (fn [{:keys [foreign url file provides requires]  :as js-map}]
          (let [url (or url (io/resource file))]
            (merge
              (javascript-file foreign url provides requires)
              js-map)))
        required-js)
      (when (-> (clojure.core/deref env/*compiler*)
             :options
             :emit-constants)
        [(constants-javascript-file opts)])
      inputs)))
(defn source-on-disk
  "Ensure that the given IJavaScript exists on disk in the output directory.\n   Return updated IJavaScript with the new location if necessary."
  [opts js]
  (if (write-js? js)
    (write-javascript opts js)
    (let [source-url (:source-url js)
          out-file (when-let [ns (and
                                   (:source-map opts)
                                   source-url
                                   (first (:provides js)))]
                     (io/file
                       (io/file (util/output-directory opts))
                       (util/ns->relpath ns (util/ext source-url))))]
      (when (and
              out-file
              source-url
              (or
                (not (.exists out-file))
                (util/changed? (io/file source-url) out-file)))
        (do
          (when (or ana/*verbose* (:verbose opts))
            (util/debug-prn
              "Copying"
              (str source-url)
              "to"
              (str out-file)))
          (util/mkdirs out-file)
          (spit out-file (slurp source-url))
          (.setLastModified out-file (util/last-modified source-url))))
      js)))
(defn elide-strict [js {:keys [elide-strict]  :as opts}]
  (cond->
    js
    (not (false? elide-strict))
    (string/replace #"(?m)^['\"]use strict['\"]" "            ")))
(defn requires-transpile? [out-file]
  (let [line (first (line-seq (io/reader out-file)))]
    (not (string/starts-with? line "/*TRANSPILED*/"))))
(defn deps-file
  "Return a deps file string for a sequence of inputs."
  [opts sources]
  (apply
    str
    (map (fn* [p1__12919#] (add-dep-string opts p1__12919#)) sources)))
(defn transpile-options []
  (doto
    (CompilerOptions.)
    (.setQuoteKeywordProperties true)
    (.setSkipNonTranspilationPasses true)
    (.setVariableRenaming VariableRenamingPolicy/OFF)
    (.setPropertyRenaming PropertyRenamingPolicy/OFF)
    (.setWrapGoogModulesForWhitespaceOnly false)
    (.setPrettyPrint true)
    (.setSourceMapOutputPath "/dev/null")
    (.setSourceMapIncludeSourcesContent true)
    (.setWarningLevel (es5-warnings) CheckLevel/OFF)))
(defn target-file-for-cljs-ns [ns-sym output-dir]
  (util/to-target-file
    (util/output-directory {:output-dir output-dir})
    {:ns ns-sym}))
(defn preloads
  ([syms] (preloads syms nil))
  ([syms mode]
    (letfn
      [(preload-str
         [sym]
         (str
           (when (= :browser mode) "document.write('');\n" "\n")))]
      (map preload-str syms))))
(defn shim-process? [{:keys [target process-shim]  :as opts}]
  (if (= :nodejs target)
    (true? process-shim)
    (not (false? process-shim))))
(defn output-deps-file [opts sources]
  (output-one-file opts (deps-file opts sources)))
(defn handle-js-modules
  "Given all Cljs sources (build inputs and dependencies in classpath)\n\n  - index all the node modules\n  - process the JS modules (preprocess + convert to Closure JS)\n  - save js-dependency-index for compilation"
  [{:keys [npm-deps target]  :as opts} js-sources compiler-env]
  (let [top-level (reduce
                    (fn [acc m]
                      (reduce
                        (fn [acc p] (assoc acc p m))
                        acc
                        (:provides m)))
                    {}
                    (if (not (false? npm-deps))
                      (index-node-modules-dir)))
        requires (->>
                   (mapcat deps/-requires js-sources)
                   (map
                     (fn*
                       [p1__13459#]
                       (-> p1__13459# ana/lib&sublib first)))
                   set)
        node-required (set/intersection
                        (set (keys top-level))
                        requires)
        expanded-libs (expand-libs (:foreign-libs opts))
        output-dir (util/output-directory opts)
        opts (update
               opts
               :foreign-libs
               (fn [libs]
                 (into
                   (if (= target :nodejs)
                     []
                     (index-node-modules node-required))
                   (into
                     expanded-libs
                     (node-inputs
                       (filter
                         (fn [{:keys [module-type]}]
                           (some? module-type))
                         expanded-libs))))))
        opts (if (or
                   (nil?
                     (:js-namespaces
                       (clojure.core/deref compiler-env)))
                   (nil?
                     (:js-module-index
                       (clojure.core/deref compiler-env)))
                   (some
                     (fn [ijs]
                       (let [dest (io/file
                                    output-dir
                                    (rel-output-path
                                      (assoc ijs :foreign true)
                                      opts))]
                         (util/changed? (deps/-url ijs opts) dest)))
                     (:foreign-libs opts)))
               (process-js-modules opts)
               (:options (clojure.core/deref compiler-env)))]
    (swap!
      compiler-env
      (fn [cenv]
        (-> cenv
         (merge {:js-dependency-index (deps/js-dependency-index opts)})
         (update-in [:options] merge opts)
         (update-in
           [:node-module-index]
           (fnil into #{})
           (if (= target :nodejs)
             (map str node-required)
             (map str (keys top-level)))))))
    opts))
(defn path-relative-to
  "Generate a string which is the path to the input IJavaScript relative\n  to the specified base file."
  [base input]
  (let [base-path (util/path-seq (.getCanonicalPath base))
        input-path (util/path-seq
                     (.getCanonicalPath (io/file (deps/-url input))))
        count-base (count base-path)
        common (count
                 (take-while
                   true?
                   (map
                     (fn*
                       [p1__12907# p2__12908#]
                       (= p1__12907# p2__12908#))
                     base-path
                     input-path)))
        prefix (repeat (- count-base common 1) "..")]
    (if (= count-base common)
      (last input-path)
      (util/to-path (concat prefix (drop common input-path)) "/"))))
(defn make-convert-js-module-options [opts]
  (-> opts
   (select-keys
     [:closure-warnings
      :closure-extra-annotations
      :pretty-print
      :language-in
      :language-out
      :closure-module-roots
      :rewrite-polyfills])
   (assoc-in [:closure-warnings :non-standard-jsdoc] :off)
   (set-options (CompilerOptions.))))
(defn remove-goog-base [inputs]
  (remove
    (fn* [p1__12761#] (= (:provides p1__12761#) ["goog"]))
    inputs))
(defn node-inputs
  "EXPERIMENTAL: return the foreign libs entries as computed by running\n   the module-deps package on the supplied JavaScript entry points. Assumes\n   that the `@cljs-oss/module-deps` NPM package is either locally or globally\n   installed."
  ([entries]
    (node-inputs
      entries
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([entries opts]
    (into
      []
      (distinct
        (mapcat
          (fn* [p1__13315#] (node-module-deps p1__13315# opts))
          entries)))))
(defn npm-deps-js
  "Returns the JavaScript code to support runtime require of bundled modules."
  [node-requires]
  (str
    "module.exports = {\n"
    "  npmDeps: {\n"
    (string/join
      ",\n"
      (map
        (comp (fn* [p1__12938#] (str "    " p1__12938#)) export-dep)
        node-requires))
    "  }\n"
    "};\n"))
(clojure.core/extend-type
  clojure.lang.IPersistentMap
  deps/IJavaScript
  (-foreign? [this] (:foreign this))
  (-closure-lib? [this] (:closure-lib this))
  (-url
    ([this] (deps/-url this nil))
    ([this opts]
      (let [[url file] (if-let [url-min
                                (and
                                  (#{:simple :advanced}
                                    (:optimizations opts))
                                  (:url-min this))]
                         [url-min (:file-min this)]
                         [(:url this) (:file this)])]
        (or url (deps/to-url file)))))
  (-relative-path
    ([this] (deps/-relative-path this nil))
    ([this opts]
      (let [file (if-let [file-min (and
                                     (#{:simple :advanced}
                                       (:optimizations opts))
                                     (:file-min this))]
                   file-min
                   (:file this))
            as-file (io/as-file file)]
        (when (and as-file (not (.isAbsolute as-file))) file))))
  (-provides [this] (map name (:provides this)))
  (-requires [this] (map name (:requires this)))
  (-source
    ([this] (deps/-source this nil))
    ([this opts]
      (if-let [s (:source this)]
        s
        (with-open [reader (io/reader (deps/-url this opts))]
          (slurp reader))))))
(defn- to-absolute-path [file-str]
  (.getAbsolutePath (io/file file-str)))
(defn- alive? [proc]
  (try
    (.exitValue proc)
    false
    (catch IllegalThreadStateException _ true)))
(defmethod
  js-source-file
  BufferedInputStream
  [name source]
  (-> (SourceFile/builder)
   (.withPath name)
   (.withContent source)
   (.build)))
(defn fingerprinted-modules [modules fingerprint-info]
  (into
    {}
    (map
      (fn [[module-name module-info]]
        (let [module-info' (assoc
                             module-info
                             :output-to
                             (get-in
                               fingerprint-info
                               [module-name :output-to-fingerprint]))]
          [module-name module-info'])))
    modules))
(defmethod
  js-source-file
  JavaScriptFile
  [_ js]
  (if-let [url (deps/-url js)]
    (js-source-file (javascript-name url) (io/input-stream url))
    (when-let [source (:source js)]
      (js-source-file (javascript-name source) source))))
(defn path-from-jarfile
  "Given the URL of a file within a jar, return the path of the file\n  from the root of the jar."
  [url]
  (last (string/split (.getFile url) #"\.jar!/")))
(defn load-data-readers! [compiler]
  (swap!
    compiler
    update-in
    [:cljs.analyzer/data-readers]
    merge
    (ana/load-data-readers)))
(defn cljs-dependents-for-macro-namespaces [state namespaces]
  (map
    :name
    (let [namespaces-set (set namespaces)]
      (filter
        (fn [x]
          (not-empty
            (set/intersection
              namespaces-set
              (-> x :require-macros vals set))))
        (vals
          (:cljs.analyzer/namespaces (clojure.core/deref state)))))))
(defn module-type->keyword [module-type]
  (case
    (.name module-type)
    "NONE"
    :none
    "GOOG"
    :goog
    "ES6"
    :es6
    "COMMONJS"
    :commonjs
    "JSON"
    :json
    "IMPORTED_SCRIPT"
    :imported-script))
(defmethod
  javascript-name
  URL
  [url]
  (if url (.getPath url) "cljs/user.js"))
(defn- module-entries
  "Return the module entries of `compile-opts` as a set."
  [compile-opts]
  (->>
    compile-opts
    :modules
    vals
    (map :entries)
    (remove nil?)
    (apply concat)
    (set)))
(defn transpile [{:keys [language-out] 
                  :or {language-out :es3} 
                  :as opts}
                 rsc
                 {:keys [module lang]  :as js}]
  (let [source (slurp rsc)
        source' (if (and
                      lang
                      (<
                        (.indexOf
                          lang-level
                          (expand-lang-key language-out))
                        (.indexOf lang-level (expand-lang-key lang))))
                  (closure-transpile (util/path rsc) source opts)
                  source)]
    (str
      "/*TRANSPILED*/"
      (cond-> source' (= :goog module) add-goog-load))))
(defmethod
  javascript-name
  String
  [s]
  (if-let [name (first (deps/-provides s))] name "cljs/user.js"))
(defmethod
  javascript-name
  JavaScriptFile
  [js]
  (when-let [url (deps/-url js)] (javascript-name url)))
(defn bundle? [opts] (false? (:nodejs-rt opts)))
(defn add-dep-string
  "Return a goog.addDependency string for an input."
  [opts input]
  (letfn
    [(ns-list
       [coll]
       (when (seq coll)
         (apply
           str
           (interpose
             ", "
             (map
               (fn* [p1__12912#] (str "'" (comp/munge p1__12912#) "'"))
               coll)))))]
    (str
      "goog.addDependency(\""
      (path-relative-to
        (io/file (util/output-directory opts) "goog" "base.js")
        input)
      "\", ["
      (ns-list (deps/-provides input))
      "], ["
      (ns-list
        (cond->>
          (deps/-requires input)
          (= :nodejs (:target opts))
          (filter (complement ana/node-module-dep?))))
      "]"
      (if (deps/-foreign? input) ", {'foreign-lib': true}")
      ");\n")))
(defn fingerprint-out-file [content out-file]
  (let [dir (.getParent out-file)
        fn (.getName out-file)
        idx (.lastIndexOf fn ".")
        ext (subs fn (inc idx))
        name (subs fn 0 idx)]
    (io/file
      dir
      (str
        name
        "-"
        (string/lower-case (util/content-sha content 7))
        "."
        ext))))
(defn expand-lang-key [key]
  (keyword (string/replace (name key) #"^es" "ecmascript")))
(defn output-bootstrap [{:keys [target target-fn]  :as opts}]
  (when (or
          (and
            (#{:nodejs} target)
            (not= (:optimizations opts) :whitespace))
          target-fn)
    (let [target-str (name target)
          outfile (io/file
                    (util/output-directory opts)
                    "goog"
                    "bootstrap"
                    (str target-str ".js"))]
      (when-let [bootstrap-file (io/resource
                                  (str
                                    "cljs/bootstrap_"
                                    target-str
                                    ".js"))]
        (util/mkdirs outfile)
        (spit outfile (slurp bootstrap-file))))))
(defn add-goog-load [source]
  (let [sb (StringBuilder.)
        module (-> (SimpleDependencyInfo/builder "" "")
                (.setGoogModule true)
                .build)
        bundler (ClosureBundler.)]
    (.appendTo bundler sb module source)
    (.toString sb)))
(defn export-dep [dep] (str "\"" dep "\": require('" dep "')"))
(defn validate-opts [opts]
  (check-output-to opts)
  (check-output-dir opts)
  (check-source-map opts)
  (check-source-map-path opts)
  (check-output-wrapper opts)
  (check-node-target opts)
  (check-preloads opts)
  (check-cache-analysis-format opts)
  (check-main opts)
  opts)
(defn index-node-modules-dir
  ([]
    (index-node-modules-dir
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([opts]
    (let [module-fseq (util/module-file-seq)]
      (node-file-seq->libs-spec module-fseq opts))))
(defn add-header [opts js] (str (make-preamble opts) js))
(defmethod
  js-source-file
  String
  [name source]
  (-> (SourceFile/builder)
   (.withPath name)
   (.withContent source)
   (.build)))
(defn add-goog-base [inputs]
  (cons
    (javascript-file nil (io/resource "goog/base.js") ["goog"] nil)
    inputs))
(defmethod
  js-source-file
  File
  [_ source]
  (-> (SourceFile/builder)
   (.withPath (.toPath source))
   (.withCharset StandardCharsets/UTF_8)
   (.build)))
(defn- constants-filename
  "Returns the filename of the constants table."
  [opts]
  (str
    (util/output-directory opts)
    File/separator
    (string/replace (str ana/constants-ns-sym) "." File/separator)
    ".js"))
(defn add-externs-sources [opts]
  (cond->
    opts
    (:infer-externs opts)
    (assoc
      :externs-sources
      (load-externs (dissoc opts :infer-externs)))))
(defn make-closure-compiler []
  (let [compiler (com.google.javascript.jscomp.Compiler.)]
    (com.google.javascript.jscomp.Compiler/setLoggingLevel
      Level/WARNING)
    compiler))
(defn ensure-module-opts [opts]
  (update
    opts
    :modules
    (fn* [p1__13240#] (ensure-cljs-base-module p1__13240# opts))))
(defn es5-warnings []
  (DiagnosticGroup.
    (into-array
      DiagnosticType
      [(DiagnosticType/error "JSC_CANNOT_CONVERT" "")])))
(defn foreign-source? [js]
  (and (satisfies? deps/IJavaScript js) (deps/-foreign? js)))
(defn transpile? [opts {:keys [module lang]}] (or module lang))
(defn index-node-modules
  ([modules]
    (index-node-modules
      modules
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([modules opts]
    (let [node-modules (io/file "node_modules")]
      (if (and
            (not (empty? modules))
            (.exists node-modules)
            (.isDirectory node-modules))
        (let [modules (into #{} (map name) modules)
              deps-file (io/file
                          (util/output-directory opts)
                          "cljs$node_modules.js")
              old-contents (when (.exists deps-file) (slurp deps-file))
              new-contents (let [sb (StringBuffer.)]
                             (run!
                               (fn*
                                 [p1__13319#]
                                 (.append
                                   sb
                                   (str
                                     "require('"
                                     p1__13319#
                                     "');\n")))
                               modules)
                             (str sb))]
          (util/mkdirs deps-file)
          (if (or
                (not= old-contents new-contents)
                (nil? env/*compiler*)
                (nil?
                  (:cljs.closure/transitive-dep-set
                    (clojure.core/deref env/*compiler*))))
            (do
              (spit deps-file new-contents)
              (let [transitive-js (node-inputs
                                    [{:file
                                      (.getAbsolutePath deps-file)}]
                                    opts)]
                (when-not (nil? env/*compiler*)
                  (swap!
                    env/*compiler*
                    update-in
                    [:cljs.closure/transitive-dep-set]
                    assoc
                    modules
                    transitive-js))
                transitive-js))
            (when-not (nil? env/*compiler*)
              (get-in
                (clojure.core/deref env/*compiler*)
                [:cljs.closure/transitive-dep-set modules]))))
        []))))
(defn convert-js-modules
  "Takes a list JavaScript modules as an IJavaScript and rewrites them into a Google\n  Closure-compatible form. Returns list IJavaScript with the converted module\n  code set as source."
  [js-modules opts]
  (let [externs (quote ())
        source-files (get-source-files js-modules opts)
        options (doto
                  (make-convert-js-module-options opts)
                  (.setProcessCommonJSModules true)
                  (.setLanguageIn (lang-key->lang-mode :ecmascript6))
                  (.setLanguageOut
                    (lang-key->lang-mode
                      (:language-out opts :ecmascript3)))
                  (.setDependencyOptions (sorting-dependency-options))
                  (.setPackageJsonEntryNames
                    (package-json-entries opts)))
        closure-compiler (doto
                           (make-closure-compiler)
                           (.init externs source-files options))
        _ (.parse closure-compiler)
        _ (report-failure (.getResult closure-compiler))
        inputs-by-name (into
                         {}
                         (map
                           (juxt
                             (fn* [p1__13030#] (.getName p1__13030#))
                             identity)
                           (vals (.getInputsById closure-compiler))))]
    (.transpileAndDontCheck closure-compiler)
    (.whitespaceOnlyPasses closure-compiler)
    (map
      (partial
        add-converted-source
        closure-compiler
        inputs-by-name
        opts)
      js-modules)))
(defn- node-file-seq->libs-spec*
  "Given a sequence of non-nested node_module paths where the extension ends in\n  `.js/.json`, return lib-spec maps for each path containing at least :file,\n   :module-type, and :provides."
  [module-fseq opts]
  (letfn
    [(package-json?
       [path]
       (= "package.json" (.getName (io/file path))))
     (top-level-package-json?
       [path]
       (boolean
         (re-find
           #"node_modules[/\\](@[^/\\]+?[/\\])?[^/\\]+?[/\\]package\.json$"
           path)))
     (trim-package-json
       [s]
       (if (string/ends-with? s "package.json")
         (subs s 0 (- (count s) 12))
         s))
     (trim-relative
       [path]
       (cond-> path (string/starts-with? path "./") (subs 2)))
     (add-exports
       [pkg-jsons]
       (reduce-kv
         (fn [pkg-jsons path {:strs [exports]  :as pkg-json}]
           (if (string? exports)
             pkg-jsons
             (reduce-kv
               (fn [pkg-jsons export _]
                 (if (= "." export)
                   pkg-jsons
                   (let [export-pkg-json (io/file
                                           (trim-package-json path)
                                           (trim-relative export)
                                           "package.json")]
                     (cond->
                       pkg-jsons
                       (.exists export-pkg-json)
                       (assoc
                         (.getAbsolutePath export-pkg-json)
                         (json/read-str (slurp export-pkg-json)))))))
               pkg-jsons
               exports)))
         pkg-jsons
         pkg-jsons))]
    (let [pkg-jsons (add-exports
                      (into
                        {}
                        (comp
                          (map
                            (fn*
                              [p1__13327#]
                              (.getAbsolutePath p1__13327#)))
                          (filter top-level-package-json?)
                          (map
                            (fn [path] [path
                                        (json/read-str
                                          (slurp path))])))
                        module-fseq))]
      (into
        []
        (comp
          (map (fn* [p1__13328#] (.getAbsolutePath p1__13328#)))
          (map
            (fn [path]
              (merge
                {:file path  :module-type :es6}
                (when-not (package-json? path)
                  (let [pkg-json-main (some
                                        (fn 
                                          [[pkg-json-path
                                            {:as pkg-json 
                                             :strs [name]}]]
                                          (let 
                                            [entries
                                             (package-json-entries
                                               opts)
                                             entry
                                             (first
                                               (keep
                                                 (partial get pkg-json)
                                                 entries))]
                                            (when-not
                                              (nil? entry)
                                              (let 
                                                [entry
                                                 (trim-relative entry)
                                                 entry-path
                                                 (->
                                                  pkg-json-path
                                                  (string/replace
                                                    \\
                                                    \/)
                                                  trim-package-json
                                                  (str entry))]
                                                (some
                                                  (fn 
                                                    [candidate]
                                                    (when
                                                      (=
                                                        candidate
                                                        (string/replace
                                                          path
                                                          \\
                                                          \/))
                                                      name))
                                                  (cond->
                                                    [entry-path]
                                                    (not
                                                      (or
                                                        (string/ends-with?
                                                          entry-path
                                                          ".js")
                                                        (string/ends-with?
                                                          entry-path
                                                          ".json")))
                                                    (into
                                                      [(str
                                                         entry-path
                                                         ".js")
                                                       (str
                                                         entry-path
                                                         "/index.js")
                                                       (str
                                                         entry-path
                                                         ".json")])))))))
                                        pkg-jsons)]
                    {:provides
                     (let [module-rel-name (->
                                            (subs
                                              path
                                              (.lastIndexOf
                                                path
                                                "node_modules"))
                                            (string/replace \\ \/)
                                            (string/replace
                                              #"node_modules[\\\/]"
                                              ""))
                           provides (cond->
                                      [module-rel-name
                                       (string/replace
                                         module-rel-name
                                         #"\.js(on)?$"
                                         "")]
                                      (some? pkg-json-main)
                                      (conj pkg-json-main))
                           index-replaced (string/replace
                                            module-rel-name
                                            #"[\\\/]index\.js(on)?$"
                                            "")]
                       (cond->
                         provides
                         (and
                           (boolean
                             (re-find
                               #"[\\\/]index\.js(on)?$"
                               module-rel-name))
                           (not (some #{index-replaced} provides)))
                         (conj index-replaced)))}))))))
        module-fseq))))
(defn add-converted-source [closure-compiler
                            inputs-by-name
                            opts
                            {:keys [file-min file provides requires] 
                             :as ijs}]
  (let [processed-file (if-let [min
                                (and
                                  (#{:simple :advanced}
                                    (:optimizations opts))
                                  file-min)]
                         min
                         file)
        processed-file (string/replace processed-file "\\" "/")
        input (get inputs-by-name processed-file)
        ast-root (.getAstRoot input closure-compiler)
        provides (distinct
                   (map
                     (fn*
                       [p1__13005#]
                       (ModuleNames/fileToModuleName p1__13005#))
                     (cons processed-file provides)))
        module-type (or
                      (some->
                        (.get (.getLoadFlags input) "module")
                        keyword)
                      (module-type->keyword (.getJsModuleType input)))]
    (assoc
      ijs
      :module-type
      module-type
      :source
      (str
        (apply
          str
          (map (fn [n] (str "goog.provide(\"" n "\");\n")) provides))
        (->>
          (.getRequires input)
          (map (fn [i] (if (string? i) i (.getSymbol i))))
          (remove #{"goog"})
          (map (fn [n] (str "goog.require(\"" n "\");\n")))
          (apply str))
        (.toSource closure-compiler ast-root)))))
(defn compile-loader
  "Special compilation pass for cljs.loader namespace. cljs.loader must be\n  compiled last after all inputs. This is because all inputs must be known and\n  they must already be sorted in dependency order."
  [inputs {:keys [modules]  :as opts}]
  (when-let [loader (->>
                      inputs
                      (filter
                        (fn [input]
                          (some
                            (quote #{cljs.loader "cljs.loader"})
                            (:provides input))))
                      first)]
    (let [module-uris (when (seq modules)
                        (module-graph/modules->module-uris
                          modules
                          inputs
                          opts))
          module-infos (when (seq modules)
                         (module-graph/modules->module-infos modules))]
      (swap!
        env/*compiler*
        ana/add-consts
        {(quote cljs.core/MODULE_INFOS)
         (merge
           (const-expr-form
             (clojure.core/deref env/*compiler*)
             (quote cljs.core/MODULE_INFOS))
           module-infos) 
         (quote cljs.core/MODULE_URIS)
         (merge
           (const-expr-form
             (clojure.core/deref env/*compiler*)
             (quote cljs.core/MODULE_URIS))
           module-uris)})
      (-compile
        (:source-file loader)
        (merge
          opts
          {:cache-key (util/content-sha (pr-str module-uris)) 
           :output-file
           (comp/rename-to-js (util/ns->relpath (:ns loader)))}))))
  inputs)
(defn optimize-modules
  "Use the Closure Compiler to optimize one or more Closure JSChunks. Returns\n   a dependency sorted list of module name and description tuples."
  [opts & sources]
  (assert
    (=
      (count (:modules opts))
      (count
        (into #{} (map (comp :output-to second) (:modules opts)))))
    "Each :output-to of :modules must be unique")
  (let [closure-compiler (make-closure-compiler)
        externs (load-externs opts)
        compiler-options (make-options opts)
        _ (.initOptions closure-compiler compiler-options)
        sources (if (= :whitespace (:optimizations opts))
                  (cons "var CLOSURE_NO_DEPS = true;" sources)
                  sources)
        modules (build-modules sources opts)
        inputs (map (comp :closure-module second) modules)
        _ (doseq [input inputs]
            (.sortInputsByDeps input closure-compiler))
        _ (when (or ana/*verbose* (:verbose opts))
            (util/debug-prn
              "Applying optimizations"
              (:optimizations opts)
              "to"
              (count sources)
              "sources"))
        result (.compileModules
                 closure-compiler
                 externs
                 inputs
                 compiler-options)
        source-map (when (:source-map opts)
                     (.getSourceMap closure-compiler))]
    (assert
      (or (nil? (:source-map opts)) source-map)
      "Could not create source maps for modules")
    (if (.success result)
      (do
        (write-variable-maps result opts)
        (vec
          (for
            [[name {:keys [output-to closure-module]  :as module}]
             modules]
            [name
             (merge
               (assoc
                 module
                 :source
                 (do
                   (when source-map (.reset source-map))
                   (.toSource closure-compiler closure-module)))
               (when source-map
                 (let [sw (StringWriter.)
                       source-map-name (str output-to ".map.closure")]
                   (.appendTo source-map sw source-map-name)
                   {:source-map-json (.toString sw) 
                    :source-map-name source-map-name})))])))
      (report-failure result))))
(defn js-dependencies
  "Given a sequence of Closure namespace strings, return the list of\n  all dependencies. The returned list includes all Google and\n  third-party library dependencies.\n\n  Third-party libraries are configured using the :libs option where\n  the value is a list of directories containing third-party\n  libraries."
  [opts requires]
  (loop [requires requires visited (set requires) deps #{}]
    (if (seq requires)
      (let [node (or
                   (get
                     ((clojure.core/deref env/*compiler*)
                       :js-dependency-index)
                     (first requires))
                   (deps/find-classpath-lib (first requires)))
            new-req (remove
                      (fn* [p1__12650#] (contains? visited p1__12650#))
                      (into (:requires node) (:require-types node)))]
        (recur
          (into (rest requires) new-req)
          (into visited new-req)
          (conj deps node)))
      (remove nil? deps))))
(defn emit-optimized-source-map
  "Given a JSON parsed Google Closure JavaScript to JavaScript source map,\n   the entire list of original IJavaScript sources output a merged JavaScript\n   to ClojureScript source map file with the given file name. opts should\n   supply :preamble-line-count and :foreign-deps-line-count if they are\n   relevant."
  [sm-json sources name opts]
  (let [closure-source-map (sm/decode-reverse sm-json)]
    (loop [sources (seq sources)
           relpaths {}
           merged (sorted-map-by
                    (sm/source-compare
                      (remove
                        nil?
                        (map
                          (fn [source]
                            (if-let [source-url (:source-url source)]
                              (.getPath source-url)
                              (if-let [url (:url source)]
                                (.getPath url))))
                          sources))))]
      (if sources
        (let [source (first sources)]
          (recur
            (next sources)
            (let [{:keys [provides source-url]} source]
              (if (and provides source-url)
                (assoc
                  relpaths
                  (.getPath source-url)
                  (util/ns->relpath
                    (first provides)
                    (util/ext source-url)))
                relpaths))
            (if-let [url (:url source)]
              (let [path (.getPath url)]
                (if-let [compiled (get-in
                                    (clojure.core/deref env/*compiler*)
                                    [:cljs.compiler/compiled-cljs
                                     path])]
                  (if-let [source-url (:source-url source)]
                    (assoc
                      merged
                      (.getPath source-url)
                      (sm/merge-source-maps
                        (:source-map compiled)
                        (get closure-source-map path)))
                    merged)
                  (assoc merged path (get closure-source-map path))))
              merged)))
        (spit
          (io/file name)
          (sm/encode
            merged
            {:output-dir (util/output-directory opts) 
             :relpaths relpaths 
             :file name 
             :lines
             (+
               (:lineCount sm-json)
               (:preamble-line-count opts 0)
               (:foreign-deps-line-count opts 0)
               2) 
             :source-map-path (:source-map-path opts) 
             :preamble-line-count
             (+
               (:preamble-line-count opts 0)
               (:foreign-deps-line-count opts 0)) 
             :source-map-timestamp (:source-map-timestamp opts) 
             :source-map (:source-map opts) 
             :source-map-pretty-print
             (:source-map-pretty-print opts)}))))))
(defn write-javascript
  "Write or copy a JavaScript file to output directory. Only write if the file\n   does not already exist. Return IJavaScript for the file on disk at the new\n   location."
  [{:keys [optimizations]  :as opts} js]
  (let [out-dir (io/file (util/output-directory opts))
        out-name (rel-output-path js opts)
        out-file (io/file out-dir out-name)
        res (or (:url js) (:source-file js))
        js-module? (and
                     res
                     out-dir
                     (.startsWith (util/path res) (util/path out-dir)))
        transpile? (transpile? opts js)
        ijs (merge
              {:requires (deps/-requires js) 
               :provides (deps/-provides js) 
               :group (:group js)}
              (when-not js-module?
                {:url (deps/to-url out-file) 
                 :out-file (.toString out-file)}))]
    (when (and
            (not js-module?)
            (or
              (not (.exists out-file))
              (and res (util/changed? out-file res))
              (and
                transpile?
                (or
                  (not= :none optimizations)
                  (requires-transpile? out-file)))))
      (when (and res (or ana/*verbose* (:verbose opts)))
        (util/debug-prn "Copying" (str res) "to" (str out-file)))
      (util/mkdirs out-file)
      (if (and transpile? (= :none optimizations))
        (spit out-file (transpile opts res js))
        (spit out-file (deps/-source js)))
      (when res (.setLastModified out-file (util/last-modified res))))
    (if (map? js) (merge js ijs) ijs)))
(defn find-cljs-dependencies
  "Given set of cljs namespace symbols, find IJavaScript objects for the namespaces."
  [requires]
  (letfn
    [(cljs-deps
       [namespaces]
       (->>
         namespaces
         (remove
           (fn*
             [p1__12685#]
             (or
               (((clojure.core/deref env/*compiler*)
                  :js-dependency-index)
                 p1__12685#)
               (deps/find-classpath-lib p1__12685#))))
         (map cljs-source-for-namespace)
         (remove (comp nil? :uri))))]
    (loop [required-files (cljs-deps requires)
           visited (set required-files)
           cljs-namespaces #{}]
      (if (seq required-files)
        (let [next-file (first required-files)
              ns-info (ana/parse-ns (:uri next-file))
              new-req (remove
                        (fn*
                          [p1__12686#]
                          (contains? visited p1__12686#))
                        (cljs-deps
                          (cond->
                            (deps/-requires ns-info)
                            (= (quote cljs.js) (:ns ns-info))
                            (conj "cljs.core$macros"))))]
          (recur
            (into (rest required-files) new-req)
            (into visited new-req)
            (conj cljs-namespaces ns-info)))
        (disj cljs-namespaces nil)))))
(defn map->javascript-file [m]
  (merge
    (javascript-file
      (:foreign m)
      (when-let [f (or (:file m) (:url m))] (deps/to-url f))
      (when-let [sf (:source-file m)] (deps/to-url sf))
      (:provides m)
      (:requires m)
      (:lines m)
      (:source-map m))
    (when-let [source-file (:source-file m)]
      {:source-file source-file})
    (when-let [out-file (:out-file m)] {:out-file out-file})
    (when (:closure-lib m) {:closure-lib true})
    (when-let [module (:module m)] {:module module})
    (when-let [lang (:lang m)] {:lang lang})
    (when-let [ns (:ns m)] {:ns ns})
    (when (:macros-ns m) {:macros-ns true})))
(defn write-variable-maps [result opts]
  (let [var-out (:closure-variable-map-out opts)]
    (when-let [var-map (and var-out (.-variableMap result))]
      (util/mkdirs var-out)
      (io/copy
        (ByteArrayInputStream. (.toBytes var-map))
        (io/file var-out))))
  (let [prop-out (:closure-property-map-out opts)]
    (when-let [prop-map (and prop-out (.-propertyMap result))]
      (util/mkdirs prop-out)
      (io/copy
        (ByteArrayInputStream. (.toBytes prop-map))
        (io/file prop-out)))))
(defn add-preloads
  "Add :preloads to a given set of inputs (IJavaScript). Returns a new\n  list of inputs where the preloaded namespaces and their deps come immediately after\n  cljs.core or the constants table depending on the optimization setting. Any\n  files needing copying or compilation will be compiled and/or copied to the\n  appropiate location."
  [inputs opts]
  (if-not (:preloads opts)
    inputs
    (let [pred (fn [x]
                 (if (:emit-constants opts)
                   (not= [(str ana/constants-ns-sym)] (:provides x))
                   (not= ["cljs.core"] (:provides x))))
          pre (take-while pred inputs)
          post (drop-while pred inputs)
          preloads (remove
                     nil?
                     (map
                       (fn [preload]
                         (try
                           (comp/find-source preload)
                           (catch
                             Throwable
                             t
                             (util/debug-prn
                               "WARNING: preload namespace"
                               preload
                               "does not exist"))))
                       (:preloads opts)))]
      (distinct-by
        :provides
        (concat
          pre
          [(first post)]
          (-> (add-dependency-sources preloads opts)
           deps/dependency-order
           (compile-sources opts)
           (add-js-sources opts)
           deps/dependency-order)
          (next post))))))
(defn output-one-file [{:keys [output-to fingerprint]  :as opts} js]
  (let [js (elide-strict js opts)]
    (cond
      (nil? output-to) js
      (or (string? output-to) (util/file? output-to)) (let 
                                                        [f
                                                         (io/file
                                                           output-to)]
                                                        (util/mkdirs f)
                                                        (spit f js)
                                                        (when
                                                          fingerprint
                                                          (let 
                                                            [dir
                                                             (.getParent
                                                               f)
                                                             mf
                                                             (io/file
                                                               dir
                                                               "manifest.edn")
                                                             g
                                                             (fingerprint-out-file
                                                               js
                                                               f)]
                                                            (.renameTo
                                                              f
                                                              g)
                                                            (spit
                                                              mf
                                                              (pr-str
                                                                {(.toString
                                                                   f)
                                                                 (.toString
                                                                   g)})))))
      :else (println js))))
(defn add-implicit-options [{:keys [optimizations output-dir] 
                             :or
                             {optimizations :none  output-dir "out"} 
                             :as opts}]
  (let [opts (cond->
               opts
               (shim-process? opts)
               (-> (update-in
                     [:preloads]
                     (fnil conj [])
                     (quote process.env))
                (cond->
                  (not= :none optimizations)
                  (update-in
                    [:closure-defines (quote process.env/NODE_ENV)]
                    (fnil str "production"))))
               (or (:closure-defines opts) (shim-process? opts))
               (update :closure-defines normalize-closure-defines)
               (:browser-repl opts)
               (update-in
                 [:preloads]
                 (fnil conj [])
                 (quote clojure.browser.repl.preload))
               (and
                 (contains? opts :modules)
                 (not (contains? opts :stable-names)))
               (assoc :stable-names true))
        {:keys [libs foreign-libs externs]} (get-upstream-deps)
        emit-constants (or
                         (and
                           (= optimizations :advanced)
                           (not (false? (:optimize-constants opts))))
                         (:optimize-constants opts))]
    (cond->
      (-> opts
       (assoc
         :optimizations
         optimizations
         :output-dir
         output-dir
         :ups-libs
         libs
         :ups-foreign-libs
         (expand-libs foreign-libs)
         :ups-externs
         externs
         :emit-constants
         emit-constants
         :cache-analysis-format
         (:cache-analysis-format opts :transit))
       (update-in
         [:preamble]
         (fn*
           [p1__13257#]
           (into (or p1__13257# []) ["cljs/imul.js"]))))
      (:target opts)
      (assoc-in
        [:closure-defines
         (str (comp/munge (quote cljs.core/*target*)))]
        (name (:target opts)))
      (= :nodejs (:target opts))
      (merge (when (nil? (:nodejs-rt opts)) {:nodejs-rt true}))
      (= :bundle (:target opts))
      (merge
        {:hashbang false 
         :infer-externs true 
         :nodejs-rt false 
         :target :nodejs}
        (when-not (:npm-deps opts) {:npm-deps true}))
      (= optimizations :none)
      (assoc
        :cache-analysis
        (:cache-analysis opts true)
        :source-map
        (:source-map opts true))
      (:aot-cache opts)
      (assoc :cache-analysis true)
      (= optimizations :advanced)
      (cond->
        (not (false? (:static-fns opts)))
        (assoc :static-fns true)
        (not (false? (:optimize-constants opts)))
        (assoc :optimize-constants true))
      (nil? (find (:closure-warnings opts) :check-types))
      (assoc-in [:closure-warnings :check-types] :off)
      (nil? (find (:closure-warnings opts) :check-variables))
      (assoc-in [:closure-warnings :check-variables] :off)
      (nil? (:closure-module-roots opts))
      (assoc :closure-module-roots [])
      (nil? (:opts-cache opts))
      (assoc :opts-cache "cljsc_opts.edn")
      (not (contains? opts :aot-cache))
      (assoc :aot-cache false)
      (contains? opts :modules)
      (ensure-module-opts)
      (nil? (:language-in opts))
      (assoc :language-in :es6)
      (:stable-names opts)
      (as->
        opts
        (let [out-dir (if (true? (:stable-names opts))
                        output-dir
                        (:stable-names opts))]
          (merge
            {:closure-variable-map-in
             (io/file out-dir "closure_var.map") 
             :closure-variable-map-out
             (io/file out-dir "closure_var.map") 
             :closure-property-map-in
             (io/file out-dir "closure_prop.map") 
             :closure-property-map-out
             (io/file out-dir "closure_prop.map")}
            opts)))
      (nil? (:ignore-js-module-exts opts))
      (assoc :ignore-js-module-exts [".css"])
      (:warning-handlers opts)
      (update :warning-handlers resolve-warning-handlers))))
(defn expand-libs
  "EXPERIMENTAL. Given a set of libs expand any entries which only name\n   directories into a sequence of lib entries for all JS files recursively\n   found in that directory. All other options will be shared with the original\n   entry. The computed :provides assumes the specified directory is on the\n   classpath."
  [libs]
  (letfn
    [(prep-path
       [p root]
       (subs (string/replace (subs p 0 (- (count p) 3)) root "") 1))
     (path->provides
       [p]
       (let [p' (string/replace p File/separator ".")]
         (cond->
           [p']
           (string/includes? p' "_")
           (conj (string/replace p' "_" "-")))))
     (expand-lib*
       [{:keys [file]  :as lib}]
       (if-not file
         [lib]
         (let [root (.getAbsolutePath (io/file file))
               dir (io/file file)]
           (if (.isDirectory dir)
             (into
               []
               (comp
                 (filter
                   (fn*
                     [p1__13209#]
                     (.endsWith (.getName p1__13209#) ".js")))
                 (filter
                   (fn* [p1__13210#] (not (.isHidden p1__13210#))))
                 (map
                   (fn [f]
                     (let [p (.getPath f) ap (.getAbsolutePath f)]
                       (merge
                         lib
                         {:file p 
                          :provides
                          (path->provides (prep-path ap root))})))))
               (file-seq dir))
             [lib]))))]
    (into [] (mapcat expand-lib* libs))))
(defn output-unoptimized
  "Ensure that all JavaScript source files are on disk (not in jars),\n   write the goog deps file including only the libraries that are being\n   used and write the deps file for the current project.\n\n   The deps file for the current project will include third-party\n   libraries."
  [{:keys [modules]  :as opts} & sources]
  (let [disk-sources (doall
                       (map
                         (fn*
                           [p1__13093#]
                           (source-on-disk opts p1__13093#))
                         sources))
        goog-deps (io/file
                    (util/output-directory opts)
                    "goog"
                    "deps.js")
        main (:main opts)
        output-deps (fn*
                      []
                      (output-deps-file
                        (assoc
                          opts
                          :output-to
                          (str
                            (util/output-directory opts)
                            File/separator
                            "cljs_deps.js"))
                        disk-sources))]
    (util/mkdirs goog-deps)
    (spit goog-deps (slurp (io/resource "goog/deps.js")))
    (when (:debug-inputs opts)
      (util/debug-prn "DEBUG: all compiler inputs")
      (util/debug-prn (pr-str sources)))
    (cond
      modules (let [modules' (module-graph/expand-modules
                               modules
                               sources)]
                (output-deps)
                (doall
                  (map
                    (fn [[module-name _]]
                      (output-main-file
                        (merge
                          opts
                          {:module-name module-name 
                           :modules modules'})))
                    modules)))
      (and main (not= :none (:target opts))) (do
                                               (output-deps)
                                               (output-main-file opts))
      :else (output-deps-file opts disk-sources))))
(defn output-modules
  "Given compiler options, original IJavaScript sources and a sequence of\n   module name and module description tuples output module sources to disk.\n   Modules description must define :output-to and supply :source entry with\n   the JavaScript source to write to disk."
  [opts js-sources modules]
  (let [fingerprint-info (atom {})]
    (doseq [[name
             {:keys [output-to source foreign-deps]  :as module-desc}] modules]
      (assert
        (not (nil? output-to))
        (str "Module " name " does not define :output-to"))
      (assert
        (not (nil? source))
        (str "Module " name " did not supply :source"))
      (let [fdeps-str (when-not (empty? foreign-deps)
                        (foreign-deps-str opts foreign-deps))
            sm-name (when (:source-map opts) (str output-to ".map"))
            out-file (io/file output-to)
            _ (util/mkdirs out-file)
            js (as->
                 source
                 source
                 (if (= name :cljs-base)
                   (add-header opts source)
                   source)
                 (if fdeps-str (str fdeps-str "\n" source) source)
                 (elide-strict source opts)
                 (if sm-name
                   (add-source-map-link
                     (assoc
                       opts
                       :output-to
                       output-to
                       :source-map
                       sm-name)
                     source)
                   source))
            fingerprint-base? (and
                                (:fingerprint opts)
                                (= :cljs-base name))]
        (when-not fingerprint-base? (spit out-file js))
        (when (:fingerprint opts)
          (let [out-file' (fingerprint-out-file js out-file)]
            (when-not fingerprint-base? (.renameTo out-file out-file'))
            (swap!
              fingerprint-info
              update
              name
              merge
              (when fingerprint-base? {:source js})
              {:output-to (.toString output-to) 
               :output-to-fingerprint (.toString out-file')})))
        (when (:source-map opts)
          (let [sm-json-str (:source-map-json module-desc)
                sm-json (json/read-str sm-json-str :key-fn keyword)]
            (when (true? (:closure-source-map opts))
              (spit
                (io/file (:source-map-name module-desc))
                sm-json-str))
            (emit-optimized-source-map
              sm-json
              js-sources
              sm-name
              (merge
                opts
                {:source-map sm-name 
                 :preamble-line-count
                 (if (= name :cljs-base)
                   (+
                     (-
                       (count
                         (.split #"\r?\n" (make-preamble opts) -1))
                       1)
                     (if (:output-wrapper opts) 1 0)
                     (if (:fingerprint opts) 1 0))
                   0) 
                 :foreign-deps-line-count
                 (if fdeps-str
                   (- (count (.split #"\r?\n" fdeps-str -1)) 1)
                   0)}))))))
    (when (:fingerprint opts)
      (let [fi (clojure.core/deref fingerprint-info)
            g (get-in fi [:cljs-base :output-to-fingerprint])
            out (io/file g)
            dir (.getParent out)
            mnf (io/file dir "manifest.edn")
            uris (module-graph/modules->module-uris
                   (fingerprinted-modules modules fi)
                   js-sources
                   opts)]
        (spit
          mnf
          (pr-str
            (into
              {}
              (map (juxt :output-to :output-to-fingerprint))
              (vals fi))))
        (spit
          out
          (str
            "var COMPILED_MODULE_URIS = "
            (json/write-str
              (into {} (map (fn [[k v]] [(-> k name munge) v])) uris))
            ";\n"
            (get-in fi [:cljs-base :source])))))))
(defn normalize-closure-defines [defines]
  (into
    {}
    (map
      (fn [[k v]] [(if (symbol? k) (str (comp/munge k)) k) v])
      defines)))
(defn- const-expr-form
  "Returns the :const-expr form for `sym` from `compiler-state`."
  [compiler-state sym]
  (let [const-expr (get-in
                     compiler-state
                     [:cljs.analyzer/namespaces
                      (symbol (namespace sym))
                      :defs
                      (symbol (name sym))
                      :const-expr])]
    (some-> const-expr ana/const-expr->constant-value)))
(defn build
  "Given compiler options, produce runnable JavaScript. An optional source\n   parameter may be provided."
  ([opts] (build nil opts))
  ([source opts]
    (build
      source
      opts
      (if-not (nil? env/*compiler*)
        env/*compiler*
        (env/default-compiler-env
          (add-externs-sources (dissoc opts :foreign-libs))))))
  ([source opts compiler-env]
    (env/with-compiler-env
      compiler-env
      (let [orig-opts opts
            opts (add-implicit-options opts)
            _ (when (:install-deps opts)
                (check-npm-deps opts)
                (swap!
                  compiler-env
                  update-in
                  [:npm-deps-installed?]
                  (fn [installed?]
                    (if-not installed?
                      (maybe-install-node-deps! opts)
                      installed?))))
            compiler-stats (:compiler-stats opts)
            checked-arrays (or
                             (:checked-arrays opts)
                             ana/*checked-arrays*)
            static-fns? (or
                          (and
                            (= (:optimizations opts) :advanced)
                            (not (false? (:static-fns opts))))
                          (:static-fns opts)
                          ana/*cljs-static-fns*)
            sources (when source (-find-sources source opts))]
        (validate-opts opts)
        (swap!
          compiler-env
          (fn*
            [p1__13503#]
            (-> p1__13503#
             (update-in [:options] merge opts)
             (assoc :target (:target opts))
             (assoc
               :js-dependency-index
               (deps/js-dependency-index opts))
             (assoc :sources sources))))
        (binding [comp/*recompiled* (when-not
                                      (false?
                                        (:recompile-dependents opts))
                                      (atom #{}))
                  ana/*checked-arrays* checked-arrays
                  ana/parse-ns (memoize ana/parse-ns)
                  ana/*cljs-static-fns* static-fns?
                  ana/*fn-invoke-direct* (or
                                           (and
                                             static-fns?
                                             (:fn-invoke-direct opts))
                                           ana/*fn-invoke-direct*)
                  *assert* (not= (:elide-asserts opts) true)
                  ana/*load-tests* (not= (:load-tests opts) false)
                  ana/*cljs-warnings* (let 
                                        [warnings
                                         (opts :warnings true)]
                                        (merge
                                          ana/*cljs-warnings*
                                          (if
                                            (or
                                              (true? warnings)
                                              (false? warnings))
                                            (zipmap
                                              [:unprovided
                                               :undeclared-var
                                               :undeclared-ns
                                               :undeclared-ns-form]
                                              (repeat warnings))
                                            warnings)))
                  ana/*verbose* (:verbose opts)]
          (when (and
                  ana/*verbose*
                  (not (:cljs.closure/watch-triggered-build? opts)))
            (util/debug-prn
              "Options passed to ClojureScript compiler:"
              (pr-str opts)))
          (let [one-file? (and
                            (:main opts)
                            (#{:whitespace :simple :advanced}
                              (:optimizations opts)))
                source (if (or
                             one-file?
                             (and
                               (nil? source)
                               (:main opts)
                               (= :none (:optimizations opts))))
                         (let [main (:main opts)
                               uri (:uri
                                     (cljs-source-for-namespace main))]
                           (assert
                             uri
                             (str
                               "No file for namespace "
                               main
                               " exists"))
                           uri)
                         source)
                compile-opts (if one-file?
                               (assoc
                                 opts
                                 :output-file
                                 (:output-to opts))
                               opts)
                _ (load-data-readers! compiler-env)
                js-sources (env/with-compiler-env
                             (dissoc
                               (clojure.core/deref compiler-env)
                               :js-module-index)
                             (-> (if
                                   source
                                   (-find-sources source opts)
                                   (-find-sources
                                     (reduce
                                       into
                                       #{}
                                       (map
                                         (comp :entries val)
                                         (:modules opts)))
                                     opts))
                              (add-dependency-sources compile-opts)))
                opts (handle-js-modules opts js-sources compiler-env)
                js-sources (-> js-sources
                            deps/dependency-order
                            (compile-sources
                              compiler-stats
                              compile-opts)
                            ((fn*
                               [p1__13504#]
                               (map
                                 add-core-macros-if-cljs-js
                                 p1__13504#)))
                            (add-js-sources opts)
                            (cond->
                              (and
                                (= :nodejs (:target opts))
                                (:nodejs-rt opts))
                              (concat
                                [(-compile
                                   (io/resource "cljs/nodejs.cljs")
                                   (assoc
                                     opts
                                     :output-file
                                     "nodejs.js"))]))
                            deps/dependency-order
                            (add-preloads opts)
                            remove-goog-base
                            add-goog-base
                            (cond->
                              (and
                                (= :nodejs (:target opts))
                                (:nodejs-rt opts))
                              (concat
                                [(-compile
                                   (io/resource "cljs/nodejscli.cljs")
                                   (assoc
                                     opts
                                     :output-file
                                     "nodejscli.js"))]))
                            (->>
                              (map
                                (fn*
                                  [p1__13505#]
                                  (source-on-disk opts p1__13505#)))
                              doall)
                            (compile-loader opts))
                _ (when (:emit-constants opts)
                    (comp/emit-constants-table-to-file
                      (:cljs.analyzer/constant-table
                        (clojure.core/deref env/*compiler*))
                      (constants-filename opts)))
                _ (when (:infer-externs opts)
                    (comp/emit-inferred-externs-to-file
                      (reduce
                        util/map-merge
                        {}
                        (map
                          (comp :externs second)
                          (get
                            (clojure.core/deref compiler-env)
                            :cljs.analyzer/namespaces)))
                      (str
                        (util/output-directory opts)
                        "/inferred_externs.js")))
                _ (spit
                    (io/file
                      (util/output-directory opts)
                      (:opts-cache opts))
                    (pr-str orig-opts))
                optim (:optimizations opts)
                ret (if (and optim (not= optim :none))
                      (do
                        (when-let [fname (:source-map opts)]
                          (assert
                            (or
                              (nil? (:output-to opts))
                              (:modules opts)
                              (string? fname))
                            (str
                              ":source-map must name a file when using :whitespace, "
                              ":simple, or :advanced optimizations with :output-to")))
                        (if (:modules opts)
                          (->>
                            (util/measure
                              compiler-stats
                              (str
                                "Optimizing "
                                (count js-sources)
                                " sources")
                              (apply optimize-modules opts js-sources))
                            (output-modules opts js-sources))
                          (let [fdeps-str
                                (foreign-deps-str
                                  opts
                                  (filter foreign-source? js-sources))
                                opts
                                (assoc
                                  opts
                                  :foreign-deps-line-count
                                  (-
                                    (count
                                      (.split #"\r?\n" fdeps-str -1))
                                    1))]
                            (->>
                              (util/measure
                                compiler-stats
                                (str
                                  "Optimizing "
                                  (count js-sources)
                                  " sources")
                                (apply
                                  optimize
                                  opts
                                  (remove foreign-source? js-sources)))
                              (add-wrapper opts)
                              (add-source-map-link opts)
                              (str fdeps-str)
                              (add-header opts)
                              (output-one-file opts)))))
                      (do
                        (when (bundle? opts)
                          (spit
                            (io/file
                              (util/output-directory opts)
                              "npm_deps.js")
                            (npm-deps-js
                              (:node-module-index
                                (clojure.core/deref env/*compiler*)))))
                        (apply output-unoptimized opts js-sources)))]
            (output-bootstrap opts)
            (when (bundle? opts) (run-bundle-cmd opts))
            ret))))))
(defn node-module-deps
  "EXPERIMENTAL: return the foreign libs entries as computed by running\n   the module-deps package on the supplied JavaScript entry point. Assumes\n   that the `@cljs-oss/module-deps` NPM package is either locally or globally\n   installed."
  ([entry]
    (node-module-deps
      entry
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([{:keys [file]} {:keys [target]  :as opts}]
    (let [main-entries (str
                         "["
                         (->>
                           (package-json-entries opts)
                           (map
                             (fn*
                               [p1__13294#]
                               (str "'" p1__13294# "'")))
                           (string/join ","))
                         "]")
          escape-backslashes (fn*
                               [p1__13295#]
                               (string/replace p1__13295# "\\" "\\\\"))
          code (-> (slurp (io/resource "cljs/module_deps.js"))
                (string/replace "JS_FILE" (escape-backslashes file))
                (string/replace
                  "CLJS_TARGET"
                  (str "" (when target (name target))))
                (string/replace "MAIN_ENTRIES" main-entries)
                (string/replace
                  "FILE_SEPARATOR"
                  (escape-backslashes File/separator)))
          proc (-> (ProcessBuilder. ["node" "--eval" code]) .start)
          is (.getInputStream proc)
          iw (StringWriter. (* 16 1024 1024))
          es (.getErrorStream proc)
          ew (StringWriter. (* 1024 1024))
          _ (do
              (.start (Thread. (bound-fn [] (pipe proc is iw))))
              (.start (Thread. (bound-fn [] (pipe proc es ew)))))
          err (.waitFor proc)]
      (if (zero? err)
        (into
          []
          (map
            (fn [{:strs [file provides]}]
              file
              (merge
                {:file file  :module-type :es6}
                (when provides {:provides provides}))))
          (next (json/read-str (str iw))))
        (do
          (when-not (.isAlive proc)
            (binding [*out* *err*] (println (str ew))))
          [])))))
(defn javascript-file
  ([foreign url provides requires]
    (javascript-file foreign url nil provides requires nil nil))
  ([foreign url source-url provides requires lines source-map]
    (assert
      (first provides)
      (str source-url " does not provide a namespace"))
    (JavaScriptFile.
      foreign
      url
      source-url
      (map name provides)
      (map name requires)
      lines
      source-map)))
(defn build-modules
  "Given a list of IJavaScript sources in dependency order and compiler options\n   return a dependency sorted list of module name / description tuples. The\n   module descriptions will be augmented with a :closure-module entry holding\n   the Closure JSChunk. Each module description will also be augmented with\n   a :foreign-deps vector containing foreign IJavaScript sources in dependency\n   order."
  [sources opts]
  (let [sources (map
                  (fn [js]
                    (cond
                      (instance? JavaScriptFile js) js
                      (map? js) (map->JavaScriptFile js)
                      (string? js) (merge
                                     (map->javascript-file
                                       {:provides (deps/-provides js)})
                                     {:source js})
                      :else js))
                  sources)
        used (atom #{})
        modules (reduce
                  (fn [ret
                       [name
                        {:keys [entries depends-on]  :as module-desc}]]
                    (assert
                      (or (= name :cljs-base) (not (empty? entries)))
                      (str
                        "Module "
                        name
                        " does not define any :entries"))
                    (when (:verbose opts)
                      (util/debug-prn "Building module" name))
                    (let [js-module (JSChunk. (clojure.core/name name))
                          module-sources (reduce
                                           (fn 
                                             [ret entry-sym]
                                             (if-let 
                                               [entries
                                                (module-graph/find-sources-for-module-entry
                                                  entry-sym
                                                  sources)]
                                               (let 
                                                 [unused
                                                  (set/difference
                                                    entries
                                                    (clojure.core/deref
                                                      used))]
                                                 (swap!
                                                   used
                                                   into
                                                   entries)
                                                 (into ret unused))
                                               (throw
                                                 (util/compilation-error
                                                   (IllegalArgumentException.
                                                     (str
                                                       "Could not find matching namespace for "
                                                       entry-sym))))))
                                           []
                                           entries)
                          foreign-deps (atom [])]
                      (doseq [ijs module-sources]
                        (when (:verbose opts)
                          (util/debug-prn
                            "  adding entry"
                            (:provides ijs)))
                        (if-not (deps/-foreign? ijs)
                          (.add
                            js-module
                            (js-source-file (javascript-name ijs) ijs))
                          (swap! foreign-deps conj ijs)))
                      (doseq [dep depends-on]
                        (if-let [parent-module
                                 (get-in
                                   (into {} ret)
                                   [dep :closure-module])]
                          (do
                            (when (:verbose opts)
                              (util/debug-prn
                                "  module"
                                name
                                "depends on"
                                dep))
                            (.addDependency js-module parent-module))
                          (throw
                            (util/compilation-error
                              (IllegalArgumentException.
                                (str
                                  "Parent module "
                                  dep
                                  " does not exist"))))))
                      (conj
                        ret
                        [name
                         (assoc
                           module-desc
                           :closure-module
                           js-module
                           :foreign-deps
                           (clojure.core/deref foreign-deps))])))
                  []
                  (module-graph/sort-modules
                    (ensure-cljs-base-module
                      (module-graph/expand-modules
                        (:modules opts)
                        sources)
                      opts)))]
    modules))
(defn process-js-modules
  "Given the current compiler options, converts JavaScript modules to Google\n  Closure modules and writes them to disk. Adds mapping from original module\n  namespace to new module namespace to compiler env. Returns modified compiler\n  options where new modules are passed with :libs option."
  [opts]
  (let [js-modules (filter
                     :module-type
                     (concat
                       (:foreign-libs opts)
                       (:ups-foreign-libs opts)))]
    (if (seq js-modules)
      (util/measure
        (:compiler-stats opts)
        "Process JS modules"
        (let [_ (when-let [unsupported (first
                                         (filter
                                           (complement
                                             #{:es6 :commonjs})
                                           (map
                                             :module-type
                                             js-modules)))]
                  (ana/warning
                    :unsupported-js-module-type
                    (clojure.core/deref env/*compiler*)
                    unsupported))
              js-modules (into
                           []
                           (comp
                             (map
                               (fn 
                                 [lib]
                                 (let 
                                   [js (deps/load-foreign-library lib)
                                    url (str (deps/-url js opts))]
                                   (if
                                     (and
                                       url
                                       (some
                                         (fn 
                                           [ext]
                                           (.endsWith url ext))
                                         (:ignore-js-module-exts
                                           opts)))
                                     (do
                                       (when
                                         (or
                                           ana/*verbose*
                                           (:verbose opts))
                                         (util/debug-prn
                                           "Ignoring JS module"
                                           url
                                           "based on the file extension"))
                                       (assoc js :source ""))
                                     (if-let 
                                       [src (deps/-source js opts)]
                                       (assoc js :source src)
                                       (throw
                                         (ex-info
                                           (str
                                             "Could not get source for JS module")
                                           {:js-module lib 
                                            :clojure.error/phase
                                            :compilation})))))))
                             (map
                               (fn 
                                 [js]
                                 (if
                                   (:preprocess js)
                                   (preprocess-js js opts)
                                   js)))
                             (map
                               (fn 
                                 [js]
                                 (cond->
                                   (update-in
                                     js
                                     [:file]
                                     to-absolute-path)
                                   (some? (:file-min js))
                                   (update-in
                                     [:file-min]
                                     to-absolute-path)))))
                           js-modules)
              js-modules (convert-js-modules js-modules opts)]
          (reduce
            (fn [new-opts {:keys [file module-type]  :as ijs}]
              (let [ijs (write-javascript opts ijs)
                    module-name (->
                                 (deps/load-library (:out-file ijs))
                                 first
                                 :provides
                                 first)]
                (swap!
                  env/*compiler*
                  (fn*
                    [p1__13375#]
                    (assoc-in
                      p1__13375#
                      [:js-namespaces module-name]
                      {:module-type module-type})))
                (doseq [provide (:provides ijs)]
                  (swap!
                    env/*compiler*
                    (fn*
                      [p1__13376#]
                      (update-in
                        p1__13376#
                        [:js-module-index]
                        assoc
                        provide
                        {:name module-name 
                         :module-type module-type}))))
                (-> new-opts
                 (update-in [:libs] (comp vec conj) (:out-file ijs))
                 (update-in
                   [:foreign-libs]
                   (fn [libs]
                     (into
                       []
                       (remove
                         (fn*
                           [p1__13377#]
                           (=
                             (to-absolute-path (:file p1__13377#))
                             file)))
                       libs)))
                 (update-in
                   [:ups-foreign-libs]
                   (fn [libs]
                     (into
                       []
                       (remove
                         (fn*
                           [p1__13378#]
                           (=
                             (to-absolute-path (:file p1__13378#))
                             (to-absolute-path file))))
                       libs))))))
            opts
            js-modules)))
      opts)))
(defn check-node-target [{:keys [nodejs-rt optimizations]  :as opts}]
  (assert
    (not (and nodejs-rt (= optimizations :whitespace)))
    (format
      ":nodejs target not compatible with :whitespace optimizations"))
  (assert
    (not
      (and
        nodejs-rt
        (= optimizations :none)
        (not (contains? opts :main))))
    (format
      ":nodejs target with :none optimizations requires a :main entry")))
(defn lib-rel-path [{:keys [lib-path url provides]  :as ijs}]
  (if (nil? lib-path)
    (util/ns->relpath (first provides) "js")
    (if (.endsWith lib-path ".js")
      (util/get-name url)
      (let [path (util/path url)
            lib-path (util/normalize-path lib-path)]
        (subs
          path
          (+ (inc (.lastIndexOf path lib-path)) (.length lib-path)))))))
(defn- package-json-entries
  "Takes options and returns a sequence with the desired order of package.json\n   entries for the given :package-json-resolution mode. If no mode is provided,\n   defaults to :webpack (if no target is set) and :nodejs (if the target is\n   :nodejs)."
  [opts]
  {:pre
   [(or
      (= (:package-json-resolution opts) :webpack)
      (= (:package-json-resolution opts) :nodejs)
      (and
        (sequential? (:package-json-resolution opts))
        (every? string? (:package-json-resolution opts)))
      (not (contains? opts :package-json-resolution)))]}
  (let [modes {:nodejs ["main"]  :webpack ["browser" "module" "main"]}]
    (if-let [mode (:package-json-resolution opts)]
      (if (sequential? mode) mode (get modes mode))
      (case (:target opts) :nodejs (:nodejs modes) (:webpack modes)))))
(clojure.core/extend-type
  URL
  Compilable
  (-compile
    [this opts]
    (case
      (.getProtocol this)
      "file"
      (-compile (io/file this) opts)
      "jar"
      (compile-from-jar this opts)))
  (-find-sources
    [this opts]
    (case
      (.getProtocol this)
      "file"
      (-find-sources (io/file this) opts)
      "jar"
      (find-jar-sources this opts))))
(defn foreign-deps-str [opts sources]
  (letfn
    [(to-js-str
       [ijs]
       (if-let [url (or
                      (and
                        (#{:simple :advanced} (:optimizations opts))
                        (:url-min ijs))
                      (:url ijs))]
         (slurp url)
         (throw
           (util/compilation-error
             (IllegalArgumentException.
               (str "Foreign lib " ijs " does not exist"))))))]
    (str (string/join "\n" (map to-js-str sources)) "\n")))
(defn- sorting-dependency-options []
  (try
    (if (contains?
          (:flags (clojure.reflect/reflect DependencyOptions))
          :abstract)
      (eval
        (quote
          (do
            (import
              (quote (com.google.javascript.jscomp DependencyOptions)))
            (DependencyOptions/sortOnly))))
      (doto (DependencyOptions.) (.setDependencySorting true)))))
(defn maybe-install-node-deps! [{:keys [deps-cmd npm-deps verbose] 
                                 :or {deps-cmd "npm"} 
                                 :as opts}]
  (let [npm-deps (merge
                   (if (map? npm-deps) npm-deps {})
                   (compute-upstream-npm-deps opts))]
    (when-not (empty? npm-deps)
      (let [pkg-json (io/file "package.json")]
        (when (or ana/*verbose* verbose)
          (util/debug-prn "Installing Node.js dependencies"))
        (when-not (.exists pkg-json) (spit pkg-json "{}"))
        (let [proc (-> (ProcessBuilder.
                         (into
                           (cond->>
                             [deps-cmd
                              ({"npm" "install"  "yarn" "add"}
                                deps-cmd)
                              "@cljs-oss/module-deps"]
                             util/windows?
                             (into ["cmd" "/c"]))
                           (map
                             (fn [[dep version]]
                               (str (name dep) "@" version)))
                           npm-deps))
                    .start)
              is (.getInputStream proc)
              iw (StringWriter. (* 16 1024 1024))
              es (.getErrorStream proc)
              ew (StringWriter. (* 1024 1024))
              _ (do
                  (.start (Thread. (bound-fn [] (pipe proc is iw))))
                  (.start (Thread. (bound-fn [] (pipe proc es ew)))))
              err (.waitFor proc)]
          (when (and (not (zero? err)) (not (.isAlive proc)))
            (println (str ew)))))
      true)))
(defn ->js-source-files [sources]
  (doall
    (map
      (fn [src]
        (let [src' (cond->
                     src
                     (and (not (record? src)) (map? src))
                     map->javascript-file)]
          (js-source-file (javascript-name src') src')))
      sources)))
(clojure.core/extend-type
  File
  Compilable
  (-compile
    [this opts]
    (if (.isDirectory this)
      (compile-dir this opts)
      (compile-file this opts)))
  (-find-sources
    [this _]
    (if (.isDirectory this)
      (comp/find-root-sources this)
      [(comp/find-source this)])))
(defn compile-sources
  "Takes dependency ordered list of IJavaScript compatible maps from parse-ns\n  and compiles them."
  ([inputs opts] (compile-sources inputs (:compiler-stats opts) opts))
  ([inputs compiler-stats opts]
    (if (:parallel-build opts)
      (parallel-compile-sources inputs compiler-stats opts)
      (util/measure
        compiler-stats
        "Compile sources"
        (binding [comp/*inputs* (zipmap (map :ns inputs) inputs)]
          (doall
            (for
              [ns-info inputs]
              (-compile
                (or (:source-file ns-info) (:source-forms ns-info))
                (merge
                  opts
                  {:output-file
                   (comp/rename-to-js
                     (util/ns->relpath (:ns ns-info)))})))))))))
(defn add-core-macros-if-cljs-js
  "If a compiled entity is the cljs.js namespace, explicitly\n  add the cljs.core macros namespace dependency to it."
  [compiled]
  (cond->
    compiled
    (= ["cljs.js"] (into [] (map str) (deps/-provides compiled)))
    (update-in [:requires] concat ["cljs.core$macros"])))
(defn add-source-map-link [{:keys [source-map output-to]  :as opts} js]
  (if source-map
    (if (= output-to :print)
      (str js "\n//# sourceMappingURL=" source-map "\n\n")
      (str
        js
        "\n//# sourceMappingURL="
        (path-relative-to (io/file output-to) {:url source-map})
        "\n\n"))
    js))
(defn load-externs
  "Externs are JavaScript files which contain empty definitions of\n  functions which will be provided by the environment. Any function in\n  an extern file will not be renamed during optimization.\n\n  Options may contain an :externs key with a list of file paths to\n  load. The :use-only-custom-externs flag may be used to indicate that\n  the default externs should be excluded."
  [{:keys
    [externs use-only-custom-externs target ups-externs infer-externs] 
    :as opts}]
  (let [validate (fn validate [p us]
                   (if (empty? us)
                     (throw
                       (util/compilation-error
                         (IllegalArgumentException.
                           (str "Extern " p " does not exist"))))
                     us))
        filter-cp-js (fn [paths]
                       (for [p paths u (deps/find-js-classpath p)] u))
        filter-js (fn [paths]
                    (for [p paths u (deps/find-js-resources p)] u))
        add-target (fn [ext]
                     (cons
                       (io/resource "cljs/externs.js")
                       (if (= :nodejs target)
                         (cons
                           (io/resource "cljs/nodejs_externs.js")
                           (or ext []))
                         ext)))
        load-js (fn [ext]
                  (map
                    (fn*
                      [p1__12247#]
                      (js-source-file
                        (.getFile p1__12247#)
                        (slurp p1__12247#)))
                    ext))]
    (let [js-sources (-> externs filter-js add-target load-js)
          ups-sources (-> ups-externs filter-cp-js load-js)
          all-sources (vec (concat js-sources ups-sources))]
      (cond->
        (if use-only-custom-externs
          all-sources
          (into all-sources (CommandLineRunner/getDefaultExterns)))
        infer-externs
        (conj
          (js-source-file
            nil
            (io/file
              (util/output-directory opts)
              "inferred_externs.js")))))))
(defrecord
  JavaScriptFile
  [foreign url source-url provides requires lines source-map]
  deps/IJavaScript
  (-foreign? [this] foreign)
  (-closure-lib? [this] (:closure-lib this))
  (-url [this] url)
  (-url [this opts] url)
  (-relative-path [this] nil)
  (-relative-path [this opts] nil)
  (-provides [this] provides)
  (-requires [this] requires)
  (-source [this] (deps/-source this nil))
  (-source
    [this opts]
    (with-open [reader (io/reader url)] (slurp reader)))
  ISourceMap
  (-source-url [this] source-url)
  (-source-map [this] source-map))
(defn check-main [{:keys [main]  :as opts}]
  (when main
    (assert
      (or (symbol? main) (string? main))
      (format ":main must be a symbol or string, got %s instead" main))
    (when (symbol? main)
      (assert
        (not (string/starts-with? (str main) "'"))
        (format
          ":main must be an unquoted symbol, got %s instead"
          main)))))
(defn cljs-source-for-namespace
  "Given a namespace return the corresponding source with either a .cljs or\n  .cljc extension."
  [ns]
  (if (= "cljs.core$macros" (str ns))
    (let [relpath "cljs/core.cljc"]
      {:relative-path relpath  :uri (io/resource relpath)  :ext :cljc})
    (let [path (-> (munge ns) (string/replace \. \/))
          relpath (str path ".cljs")]
      (if-let [res (io/resource relpath)]
        {:relative-path relpath  :uri res  :ext :cljs}
        (let [relpath (str path ".cljc")]
          (if-let [res (io/resource relpath)]
            {:relative-path relpath  :uri res  :ext :cljc}))))))
(defn write-js?
  "Returns true if IJavaScript instance needs to be written/copied to output\n  directory. True when in memory, in a JAR, or if foreign library."
  [js]
  (try
    (let [url (deps/-url js)]
      (or
        (not url)
        (= (.getProtocol url) "jar")
        (deps/-closure-lib? js)
        (deps/-foreign? js)))
    (catch
      Throwable
      t
      (throw
        (util/compilation-error
          (Exception.
            (str "Could not write JavaScript " (pr-str js))))))))
(defn preamble-from-paths [paths]
  (when-let [missing (seq (remove io/resource paths))]
    (ana/warning
      :preamble-missing
      (clojure.core/deref env/*compiler*)
      {:missing (sort missing)}))
  (let [resources (remove nil? (map io/resource paths))]
    (str (string/join "\n" (map slurp resources)) "\n")))
(defn check-preloads [{:keys [preloads optimizations]  :as opts}]
  (when (and
          (some? preloads)
          (not= preloads (quote [process.env]))
          (not= optimizations :none))
    (binding [*out* *err*]
      (println
        "WARNING: :preloads should only be specified with :none optimizations"))))
(defn check-output-wrapper [{:keys [output-wrapper optimizations]}]
  (assert
    (not (and output-wrapper (= :whitespace optimizations)))
    ":output-wrapper cannot be combined with :optimizations :whitespace"))
(defn output-main-file
  "Output an entry point. In the non-modules case, opts is simply compiler\n  options. When emitting a module entry point, opts must contain :module-name."
  [opts]
  (assert
    (or
      (not (contains? opts :module-name))
      (get (:modules opts) (:module-name opts)))
    (str "Module " (:module-name opts) " does not exist"))
  (let [module (get (:modules opts) (:module-name opts))]
    (output-one-file
      (merge opts (when module {:output-to (:output-to module)}))
      (if-let [target-fn (opts-fn :target-fn opts)]
        (target-fn opts)
        (let [asset-path (or
                           (:asset-path opts)
                           (util/output-directory opts))
              closure-defines (json/write-str (:closure-defines opts))]
          (case
            (:target (cond-> opts (bundle? opts) (dissoc :target)))
            :nodejs
            (add-header
              opts
              (str
                (when (or
                        (not module)
                        (= :cljs-base (:module-name opts)))
                  (str
                    "var path = require(\"path\");\n"
                    "try {\n"
                    "    require(\"source-map-support\").install();\n"
                    "} catch(err) {\n"
                    "}\n"
                    "require(path.join(path.resolve(\".\"),\""
                    asset-path
                    "\",\"goog\",\"bootstrap\",\"nodejs.js\"));\n"
                    "require(path.join(path.resolve(\".\"),\""
                    asset-path
                    "\",\"cljs_deps.js\"));\n"
                    "goog.global.CLOSURE_UNCOMPILED_DEFINES = "
                    closure-defines
                    ";\n"
                    (apply str (preloads (:preloads opts)))))
                (apply
                  str
                  (map
                    (fn [entry]
                      (str
                        "goog.require(\""
                        (comp/munge entry)
                        "\");\n"))
                    (if-let [entries (when module (:entries module))]
                      entries
                      [(:main opts)])))
                (when (:nodejs-rt opts)
                  "goog.require(\"cljs.nodejscli\");\n")))
            :webworker
            (str
              (when (or
                      (not module)
                      (= :cljs-base (:module-name opts)))
                (str
                  "var CLOSURE_BASE_PATH = \""
                  asset-path
                  "/goog/\";\n"
                  "var CLOSURE_UNCOMPILED_DEFINES = "
                  closure-defines
                  ";\n"
                  "var CLOSURE_IMPORT_SCRIPT = (function(global) { return function(src) {global['importScripts'](src); return true;};})(this);\n"
                  "if(typeof goog == 'undefined') importScripts(\""
                  asset-path
                  "/goog/base.js\");\n"
                  "importScripts(\""
                  asset-path
                  "/cljs_deps.js\");\n"
                  (apply str (preloads (:preloads opts)))))
              (apply
                str
                (map
                  (fn [entry]
                    (when-not (= "goog" entry)
                      (str
                        "goog.require(\""
                        (comp/munge entry)
                        "\");\n")))
                  (if-let [entries (when module (:entries module))]
                    entries
                    (when-let [main (:main opts)] [main])))))
            (str
              (when (bundle? opts)
                "import {npmDeps} from \"./npm_deps.js\";\n")
              (when (or
                      (not module)
                      (= :cljs-base (:module-name opts)))
                (str
                  "window.CLOSURE_UNCOMPILED_DEFINES = "
                  closure-defines
                  ";\n"
                  "window.CLOSURE_NO_DEPS = true;\n"
                  "if(typeof goog == \"undefined\") document.write('');\n"
                  "document.write('');\n"
                  "document.write('');\n"
                  "document.write('');\n"
                  (apply str (preloads (:preloads opts) :browser))))
              (apply
                str
                (map
                  (fn [entry]
                    (when-not (= "goog" entry)
                      (str
                        "document.write('');\n")))
                  (if-let [entries (when module (:entries module))]
                    entries
                    (when-let [main (:main opts)] [main]))))
              (when (bundle? opts)
                (str
                  "window.require = function(lib) {\n"
                  "   return npmDeps[lib];\n"
                  "}\n")))))))))
(defn add-dependency-sources
  "Given list of IJavaScript objects, produce a new sequence of IJavaScript objects\n  of all dependencies of inputs."
  ([inputs]
    (add-dependency-sources
      inputs
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([inputs compile-opts]
    (let [inputs (set inputs)
          requires (set (mapcat deps/-requires inputs))
          module-entries (module-entries compile-opts)]
      (into
        inputs
        (find-cljs-dependencies (set/union requires module-entries))))))
(clojure.core/extend-type
  String
  deps/IJavaScript
  (-foreign? [this] false)
  (-closure-lib? [this] false)
  (-url ([this] nil) ([this _] nil))
  (-relative-path ([this] nil) ([this _] nil))
  (-provides
    [this]
    (let [{:keys [provides]} (deps/parse-js-ns
                               (string/split-lines this))]
      (cond->
        provides
        (empty? provides)
        (conj (util/content-sha this 7)))))
  (-requires
    [this]
    (:requires (deps/parse-js-ns (string/split-lines this))))
  (-source ([this] this) ([this _] this)))
(defn- pipe [proc in out]
  (with-open [in (-> in InputStreamReader. BufferedReader.)]
    (loop [buf (char-array 1024)]
      (when (alive? proc)
        (try
          (let [len (.read in buf)]
            (when-not (neg? len) (.write out buf 0 len) (.flush out)))
          (catch
            IOException
            e
            (when (and
                    (alive? proc)
                    (not (.contains (.getMessage e) "Stream closed")))
              (.printStackTrace e *err*))))
        (recur buf)))))
(defn jar-file-to-disk
  "Copy a file contained within a jar to disk. Return the created file."
  ([url out-dir]
    (jar-file-to-disk
      url
      out-dir
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([url out-dir opts]
    (let [out-file (io/file out-dir (path-from-jarfile url))
          content (with-open [reader (io/reader url)] (slurp reader))]
      (when (and url (or ana/*verbose* (:verbose opts)))
        (util/debug-prn "Copying" (str url) "to" (str out-file)))
      (util/mkdirs out-file)
      (spit out-file content)
      (.setLastModified out-file (util/last-modified url))
      out-file)))
(defn- aot-cache? [opts]
  "Returns true if compilation artifacts shuold be placed in the\n  shared AOT cache."
  (and (:aot-cache opts) (clojure.core/deref USER-HOME-WRITABLE)))
(defn to-charset [charset]
  (cond
    (instance? Charset charset) charset
    (and
      (string? charset)
      (contains? string->charset (string/lower-case charset))) (get
                                                                 string->charset
                                                                 (string/lower-case
                                                                   charset))
    :else (throw
            (ex-info
              (str
                "Invalid :closure-output-charset "
                charset
                " given, only "
                (string/join ", " (keys string->charset))
                " supported ")
              {:clojure.error/phase:compilation}))))
(clojure.core/extend-type File Inputs (-paths [this] [this]))
(defn compiled-file
  "Given a map with at least a :file key, return a map with\n   {:file .. :provides .. :requires ..}.\n\n   Compiled files are cached so they will only be read once."
  [m]
  (let [path (.getPath (.toURL (:file m)))
        js (if (:provides m)
             (map->javascript-file m)
             (if-let [js (get-in
                           (clojure.core/deref env/*compiler*)
                           [:cljs.closure/compiled-cljs path])]
               js
               (read-js (:file m))))]
    (swap!
      env/*compiler*
      update-in
      [:cljs.closure/compiled-cljs]
      assoc
      path
      js)
    js))
(defn set-options
  "TODO: Add any other options that we would like to support."
  [opts compiler-options]
  (.setModuleResolutionMode
    compiler-options
    ModuleLoader$ResolutionMode/NODE)
  (when (contains? opts :pretty-print)
    (.setPrettyPrint compiler-options (:pretty-print opts)))
  (when (contains? opts :pseudo-names)
    (set!
      (.generatePseudoNames compiler-options)
      (:pseudo-names opts)))
  (when-let [lang-key (:language-in opts :ecmascript5)]
    (.setLanguageIn compiler-options (lang-key->lang-mode lang-key)))
  (when-let [lang-key (:language-out opts)]
    (.setLanguageOut compiler-options (lang-key->lang-mode lang-key)))
  (when (contains? opts :print-input-delimiter)
    (set!
      (.printInputDelimiter compiler-options)
      (:print-input-delimiter opts)))
  (when (contains? opts :closure-warnings)
    (doseq [[type level] (:closure-warnings opts)]
      (. compiler-options
       (setWarningLevel (type warning-types) (level check-level)))))
  (when (contains? opts :closure-extra-annotations)
    (. compiler-options
     (setExtraAnnotationNames
       (map name (:closure-extra-annotations opts)))))
  (when (contains? opts :closure-module-roots)
    (. compiler-options (setModuleRoots (:closure-module-roots opts))))
  (when (contains? opts :closure-generate-exports)
    (. compiler-options
     (setGenerateExports (:closure-generate-exports opts))))
  (when (contains? opts :rewrite-polyfills)
    (. compiler-options
     (setRewritePolyfills (:rewrite-polyfills opts))))
  (when (contains? opts :rename-prefix)
    (. compiler-options (setRenamePrefix (:rename-prefix opts))))
  (when (contains? opts :rename-prefix-namespace)
    (. compiler-options
     (setRenamePrefixNamespace (:rename-prefix-namespace opts))))
  (when (contains? opts :closure-variable-map-in)
    (let [var-in (io/file (:closure-variable-map-in opts))]
      (when (.exists var-in)
        (.setInputVariableMap
          compiler-options
          (VariableMap/load (.getAbsolutePath var-in))))))
  (when (contains? opts :closure-property-map-in)
    (let [prop-in (io/file (:closure-property-map-in opts))]
      (when (.exists prop-in)
        (.setInputPropertyMap
          compiler-options
          (VariableMap/load (.getAbsolutePath prop-in))))))
  (. compiler-options
   (setOutputCharset
     (to-charset (:closure-output-charset opts "UTF-8"))))
  compiler-options)
(defn check-output-dir [{:keys [output-dir]  :as opts}]
  (when (contains? opts :output-dir)
    (assert
      (string? output-dir)
      (format
        ":output-dir %s must specify a directory"
        (pr-str output-dir))))
  true)
(defn rel-output-path
  "Given a IJavaScript which points to a .js file either in memory, in a jar file,\n  or is a foreign lib, return the path relative to the output directory."
  ([js]
    (rel-output-path
      js
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([js opts]
    (let [url (deps/-url js opts)]
      (cond
        url (cond
              (deps/-closure-lib? js) (lib-rel-path js)
              (deps/-foreign? js) (or
                                    (deps/-relative-path js opts)
                                    (util/relative-name url))
              :else (path-from-jarfile url))
        (string? js) (str (util/content-sha js 7) ".js")
        :else (str (random-string 5) ".js")))))
(defn compile-from-jar
  "Compile a file from a jar if necessary. Returns IJavaScript."
  [jar-file {:keys [output-file]  :as opts}]
  (let [out-file (when output-file
                   (io/file (util/output-directory opts) output-file))
        cacheable (ana/cacheable-files
                    jar-file
                    (util/ext jar-file)
                    opts)]
    (when (or
            (nil? out-file)
            (comp/requires-compilation? jar-file out-file opts))
      (if (not (aot-cache? opts))
        (-compile
          (jar-file-to-disk jar-file (util/output-directory opts) opts)
          opts)
        (let [cache-path (ana/cache-base-path
                           (util/path jar-file)
                           opts)]
          (when (comp/requires-compilation?
                  jar-file
                  (:output-file cacheable)
                  opts)
            (-compile
              (jar-file-to-disk jar-file cache-path opts)
              (assoc opts :output-dir (util/path cache-path))))
          (copy-from-cache cache-path cacheable jar-file opts))))
    (when (or (nil? out-file) (not (.exists out-file)))
      (jar-file-to-disk jar-file (util/output-directory opts) opts))
    (compile-file
      (io/file
        (util/output-directory opts)
        (last (string/split (.getPath jar-file) #"\.jar!/")))
      opts)))
(defn preprocess-js
  "Given js-module map, apply preprocessing defined by :preprocess value in the map."
  [{:keys [preprocess]  :as js-module} opts]
  (cond
    (keyword? preprocess) (js-transforms js-module opts)
    (symbol? preprocess) (let [preprocess-var (sym->var
                                                preprocess
                                                :preprocess
                                                {:file
                                                 (:file js-module)})]
                           (try
                             (preprocess-var js-module opts)
                             (catch
                               Throwable
                               t
                               (throw
                                 (ex-info
                                   (str
                                     "Error running preprocessing function "
                                     preprocess)
                                   {:file (:file js-module) 
                                    :preprocess preprocess 
                                    :clojure.error/phase :compilation}
                                   t)))))
    :else (do
            (ana/warning
              :unsupported-preprocess-value
              (clojure.core/deref env/*compiler*)
              js-module)
            js-module)))
(clojure.core/extend-type
  String
  Compilable
  (-compile [this opts] (-compile (io/file this) opts))
  (-find-sources [this opts] (-find-sources (io/file this) opts)))
(defn report-failure [result]
  (let [errors (.errors result) warnings (.warnings result)]
    (binding [*out* *err*]
      (doseq [next (seq errors)] (println "ERROR:" (.toString next)))
      (doseq [next (seq warnings)]
        (println "WARNING:" (.toString next)))
      (when (seq errors)
        (throw
          (util/compilation-error
            (Exception. "Closure compilation failed")))))))
(defn make-options
  "Create a CompilerOptions object and set options from opts map."
  [opts]
  (let [level (case
                (:optimizations opts)
                :advanced
                CompilationLevel/ADVANCED_OPTIMIZATIONS
                :whitespace
                CompilationLevel/WHITESPACE_ONLY
                :simple
                CompilationLevel/SIMPLE_OPTIMIZATIONS)
        compiler-options (doto
                           (CompilerOptions.)
                           (.setCodingConvention
                             (ClosureCodingConvention.)))]
    (doseq [[key val] (:closure-defines opts)]
      (let [key (name key)]
        (cond
          (string? val) (.setDefineToStringLiteral
                          compiler-options
                          key
                          val)
          (number? val) (.setDefineToDoubleLiteral
                          compiler-options
                          key
                          val)
          (or (true? val) (false? val)) (.setDefineToBooleanLiteral
                                          compiler-options
                                          key
                                          val)
          :else (println
                  "value for"
                  key
                  "must be string, int, float, or bool"))))
    (if-let [extra-annotations (:closure-extra-annotations opts)]
      (. compiler-options
       (setExtraAnnotationNames (map name extra-annotations))))
    (when (:source-map opts)
      (if (:modules opts)
        (set!
          (.sourceMapOutputPath compiler-options)
          (str
            (io/file (util/output-directory opts) "cljs_modules.map")))
        (set!
          (.sourceMapOutputPath compiler-options)
          (:source-map opts)))
      (set!
        (.sourceMapDetailLevel compiler-options)
        SourceMap$DetailLevel/ALL)
      (set! (.sourceMapFormat compiler-options) SourceMap$Format/V3))
    (do
      (.setOptionsForCompilationLevel level compiler-options)
      (set-options opts compiler-options)
      compiler-options)))
(defn check-cache-analysis-format [{:keys
                                    [cache-analysis
                                     cache-analysis-format] 
                                    :as opts}]
  (assert
    (not
      (and
        cache-analysis
        ((complement #{:transit :edn}) cache-analysis-format)
        (not (nil? cache-analysis-format))))
    (format
      ":cache-analysis format must be :edn or :transit but it is: %s"
      (pr-str cache-analysis-format))))
(defn check-output-to [{:keys [output-to]  :as opts}]
  (when (contains? opts :output-to)
    (assert
      (or (string? output-to) (= :print output-to))
      (format
        ":output-to %s must specify a file or be :print"
        (pr-str output-to))))
  true)
(defn ensure-cljs-base-module
  "Ensure that compiler :modules map has :cljs-base module with defined\n  :output-to. If :output-to not provided will default to :output-dir location\n  and the name of the file will be \"cljs_base.js.\""
  ([modules]
    (ensure-cljs-base-module
      modules
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([modules opts]
    (update-in
      modules
      [:cljs-base :output-to]
      (fnil
        io/file
        (io/file (util/output-directory opts) "cljs_base.js")))))
(defn check-source-map
  "When :source-map is specified in opts, "
  [{:keys [output-to source-map output-dir optimizations]  :as opts}]
  (when (and
          (contains? opts :source-map)
          (:source-map opts)
          (not (= optimizations :none)))
    (assert
      (and
        (or (contains? opts :output-to) (contains? opts :modules))
        (contains? opts :output-dir))
      (str
        ":source-map cannot be specified without also specifying :output-dir "
        "and either :output-to or :modules if optimization setting applied"))
    (assert
      (or
        (nil? (:output-to opts))
        (:modules opts)
        (string? source-map))
      (format
        (str
          ":source-map %s must specify a file in the same directory "
          "as :output-to %s if optimization setting applied")
        (pr-str source-map)
        (pr-str output-to)))
    (assert
      (or
        (nil? (:output-to opts))
        (:modules opts)
        (in-same-dir? source-map output-to))
      (format
        (str
          ":source-map %s must specify a file in the same directory as "
          ":output-to %s if optimization setting applied")
        (pr-str source-map)
        (pr-str output-to)))
    (assert
      (or
        (nil? (:output-to opts))
        (:modules opts)
        (same-or-subdirectory-of?
          (absolute-parent output-to)
          output-dir))
      (format
        (str
          ":output-dir %s must specify a directory in :output-to's "
          "parent %s if optimization setting applied")
        (pr-str output-dir)
        (pr-str (absolute-parent output-to)))))
  (when (and (contains? opts :source-map) (= optimizations :none))
    (assert
      (util/boolean? source-map)
      (format
        ":source-map must be true or false when compiling with :optimizations :none but it is: %s"
        (pr-str source-map))))
  true)
(defn get-upstream-deps*
  "returns a merged map containing all upstream dependencies defined\n  by libraries on the classpath."
  ([]
    (get-upstream-deps*
      (. (Thread/currentThread) (getContextClassLoader))))
  ([classloader]
    (let [upstream-deps (map
                          (fn*
                            [p1__13108#]
                            (read-string (slurp p1__13108#)))
                          (enumeration-seq
                            (. classloader
                             (getResources "deps.cljs"))))]
      (apply
        merge-with
        (fn [a b]
          (if (map? a)
            (merge-with
              (fn*
                [p1__13109# p2__13110#]
                (into #{p1__13109#} #{p2__13110#}))
              a
              b)
            (concat a b)))
        upstream-deps))))
(clojure.core/extend-type
  String
  Inputs
  (-paths [this] [(io/file this)]))
(defn check-npm-deps [{:keys [npm-deps]}]
  (let [npm-deps (if (true? npm-deps) {} npm-deps)
        {ups-npm-deps :npm-deps} (get-upstream-deps)
        conflicts (filter
                    (fn [[dep v]]
                      (and (coll? v) (not (contains? npm-deps dep))))
                    ups-npm-deps)]
    (binding [*out* *err*]
      (doseq [[dep versions] conflicts]
        (println
          (str
            "WARNING: NPM dependency "
            (name dep)
            " conflicts between versions "
            (util/conjunction-str versions)
            ". Specify a version in :npm-deps or the latest will be installed."))))))
(defn optimize
  "Use the Closure Compiler to optimize one or more JavaScript files."
  [opts & sources]
  (when (or ana/*verbose* (:verbose opts))
    (util/debug-prn
      "Applying optimizations"
      (:optimizations opts)
      "to"
      (count sources)
      "sources"))
  (let [closure-compiler (make-closure-compiler)
        externs (load-externs opts)
        compiler-options (make-options opts)
        sources (if (= :whitespace (:optimizations opts))
                  (cons "var CLOSURE_NO_DEPS = true;" sources)
                  sources)
        inputs (->js-source-files sources)
        result (util/measure
                 (:compiler-stats opts)
                 "Optimizing with Google Closure Compiler"
                 (.compile
                   closure-compiler
                   externs
                   inputs
                   compiler-options))]
    (if (.success result)
      (do
        (write-variable-maps result opts)
        (let [source (.toSource closure-compiler)]
          (when-let [name (:source-map opts)]
            (let [name' (str name ".closure")
                  sw (StringWriter.)
                  sm-json-str (do
                                (.appendTo
                                  (.getSourceMap closure-compiler)
                                  sw
                                  name')
                                (.toString sw))]
              (when (true? (:closure-source-map opts))
                (spit (io/file name') sm-json-str))
              (emit-optimized-source-map
                (json/read-str sm-json-str :key-fn keyword)
                sources
                name
                (assoc
                  opts
                  :preamble-line-count
                  (+
                    (-
                      (count (.split #"\r?\n" (make-preamble opts) -1))
                      1)
                    (if (:output-wrapper opts) 1 0))))))
          source))
      (report-failure result))))
(defn- opts-fn
  "Extracts a function from opts, by default expecting a function value, but\n  converting from a namespaced symbol if needed."
  [kw opts]
  (when-let [fn-or-sym (kw opts)]
    (cond-> fn-or-sym (symbol? fn-or-sym) (sym->var kw {}))))
(defn- sym->var
  "Converts a namespaced symbol to a var, loading the requisite namespace if\n  needed. For use with a function defined under a keyword in opts. The kw and\n  ex-data arguments are used to form exceptions."
  ([sym kw] (sym->var sym kw nil))
  ([sym kw ex-data]
    (let [ns (namespace sym)
          _ (when (nil? ns)
              (throw
                (ex-info
                  (str kw " symbol " sym " is not fully qualified")
                  (merge
                    ex-data
                    {kw sym  :clojure.error/phase :compilation}))))
          var-ns (symbol ns)]
      (when (not (find-ns var-ns))
        (try
          (locking ana/load-mutex (require var-ns))
          (catch
            Throwable
            t
            (throw
              (ex-info
                (str
                  "Cannot require namespace referred by "
                  kw
                  " value "
                  sym)
                (merge
                  ex-data
                  {kw sym  :clojure.error/phase :compilation})
                t)))))
      (find-var sym))))
(defn run-bundle-cmd [opts]
  (let [cmd-type (or (#{:none} (:optimizations opts)) :default)]
    (when-let [cmd (get-in opts [:bundle-cmd cmd-type])]
      (let [{:keys [exit out err]} (try
                                     (apply sh/sh cmd)
                                     (catch
                                       Throwable
                                       t
                                       (throw
                                         (ex-info
                                           (str
                                             ":build-cmd "
                                             cmd-type
                                             " failed")
                                           {:cmd cmd}
                                           t))))]
        (when-not (== 0 exit)
          (throw
            (ex-info
              (str ":bundle-cmd " cmd-type " failed")
              {:cmd cmd 
               :exit-code exit 
               :stdout out 
               :stderr err})))))))
(clojure.core/extend-type
  clojure.lang.PersistentVector
  Compilable
  (-compile [this opts] (compile-form-seq this))
  (-find-sources [this opts] [(ana/parse-ns this opts)]))
(clojure.core/extend-type
  clojure.lang.PersistentList
  Compilable
  (-compile [this opts] (compile-form-seq [this]))
  (-find-sources [this opts] [(ana/parse-ns [this] opts)]))
(defn compile-file
  "Compile a single cljs file. If no output-file is specified, returns\n  a string of compiled JavaScript. With an output-file option, the\n  compiled JavaScript will written to this location and the function\n  returns a JavaScriptFile. In either case the return value satisfies\n  IJavaScript."
  [file {:keys [output-file]  :as opts}]
  (if output-file
    (let [out-file (io/file (util/output-directory opts) output-file)]
      (if (and (aot-cache? opts) (gitlibs-src? file))
        (let [cacheable (ana/cacheable-files file (util/ext file) opts)
              cache-path (ana/cache-base-path (util/path file) opts)]
          (if (not (.exists (:output-file cacheable)))
            (let [ret (compiled-file
                        (comp/compile-file
                          file
                          (:output-file cacheable)
                          (assoc
                            opts
                            :output-dir
                            (util/path cache-path))))]
              (copy-from-cache cache-path cacheable file opts)
              ret)
            (do
              (when-not (.exists out-file)
                (copy-from-cache cache-path cacheable file opts))
              (compiled-file
                (comp/compile-file file (.toString out-file) opts)))))
        (compiled-file
          (comp/compile-file file (.toString out-file) opts))))
    (let [path (.getPath file)]
      (binding [ana/*cljs-file* path]
        (with-open [rdr (io/reader file)]
          (compile-form-seq (ana/forms-seq* rdr path)))))))
(defn add-wrapper [{:keys [output-wrapper]  :as opts} js]
  (if output-wrapper
    (cond
      (fn? output-wrapper) (output-wrapper js)
      (string? output-wrapper) (format output-wrapper js)
      :else (str ";(function(){\n" js "\n})();\n"))
    js))
(clojure.core/extend-type
  clojure.lang.Symbol
  Compilable
  (-compile [this opts] (-compile (util/ns->source this) opts))
  (-find-sources
    [this opts]
    (-find-sources (util/ns->source this) opts)))
(defn check-source-map-path [{:keys [source-map-path]  :as opts}]
  (when (contains? opts :source-map-path)
    (assert
      (string? source-map-path)
      (format
        ":source-map-path %s must be a directory"
        source-map-path))
    (when-not (= (:optimizations opts) :none)
      (assert
        (and (contains? opts :output-to) (contains? opts :source-map))
        (str
          ":source-map-path cannot be specified without also specifying "
          ":output-to and :source-map if optimization setting applied"))))
  true)
(defmethod
  js-transforms
  :default
  [ijs opts]
  (ana/warning
    :unsupported-preprocess-value
    (clojure.core/deref env/*compiler*)
    ijs)
  ijs)
(defmethod
  js-source-file
  URL
  [_ source]
  (js-source-file _ (io/file (.getPath source))))
(defn compute-upstream-npm-deps
  ([]
    (compute-upstream-npm-deps
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([{:keys [npm-deps]}]
    (let [{ups-npm-deps :npm-deps} (get-upstream-deps)]
      (reduce
        (fn [m [dep v]]
          (cond->
            m
            (and
              (or (nil? npm-deps) (map? npm-deps))
              (not (contains? npm-deps dep)))
            (assoc dep (if (coll? v) (last (sort v)) v))))
        {}
        ups-npm-deps))))
(clojure.core/extend-type
  clojure.lang.IPersistentSet
  Compilable
  (-compile
    [this opts]
    (doall
      (map
        (comp
          (fn* [p1__12600#] (-compile p1__12600# opts))
          util/ns->source)
        this)))
  (-find-sources
    [this opts]
    (into
      []
      (mapcat (fn* [p1__12601#] (-find-sources p1__12601# opts)))
      this)))
(extend-protocol
  deps/IJavaScript
  String
  (-foreign? [this] false)
  (-closure-lib? [this] false)
  (-url ([this] nil) ([this _] nil))
  (-relative-path ([this] nil) ([this _] nil))
  (-provides
    [this]
    (let [{:keys [provides]} (deps/parse-js-ns
                               (string/split-lines this))]
      (cond->
        provides
        (empty? provides)
        (conj (util/content-sha this 7)))))
  (-requires
    [this]
    (:requires (deps/parse-js-ns (string/split-lines this))))
  (-source ([this] this) ([this _] this))
  clojure.lang.IPersistentMap
  (-foreign? [this] (:foreign this))
  (-closure-lib? [this] (:closure-lib this))
  (-url
    ([this] (deps/-url this nil))
    ([this opts]
      (let [[url file] (if-let [url-min
                                (and
                                  (#{:simple :advanced}
                                    (:optimizations opts))
                                  (:url-min this))]
                         [url-min (:file-min this)]
                         [(:url this) (:file this)])]
        (or url (deps/to-url file)))))
  (-relative-path
    ([this] (deps/-relative-path this nil))
    ([this opts]
      (let [file (if-let [file-min (and
                                     (#{:simple :advanced}
                                       (:optimizations opts))
                                     (:file-min this))]
                   file-min
                   (:file this))
            as-file (io/as-file file)]
        (when (and as-file (not (.isAbsolute as-file))) file))))
  (-provides [this] (map name (:provides this)))
  (-requires [this] (map name (:requires this)))
  (-source
    ([this] (deps/-source this nil))
    ([this opts]
      (if-let [s (:source this)]
        s
        (with-open [reader (io/reader (deps/-url this opts))]
          (slurp reader))))))
(defn parallel-compile-sources [inputs compiler-stats opts]
  (module-graph/validate-inputs inputs)
  (let [deque (LinkedBlockingDeque. inputs)
        input-set (atom
                    (into #{} (comp (remove nil?) (map :ns)) inputs))
        cnt (+
              2
              (int
                (* 0.6 (.. Runtime getRuntime availableProcessors))))
        latch (CountDownLatch. cnt)
        es (Executors/newFixedThreadPool cnt)
        compiled (atom [])
        failed (atom false)]
    (dotimes [_ cnt]
      (.execute
        es
        (bound-fn
          []
          (compile-task deque input-set compiled opts failed)
          (.countDown latch))))
    (util/measure compiler-stats "Compile sources" (.await latch))
    (.shutdown es)
    (when (clojure.core/deref failed)
      (throw (clojure.core/deref failed)))
    (clojure.core/deref compiled)))
(defn absolute-parent [path]
  (.getParent (.getAbsoluteFile (io/file path))))
(defn compile-task [deque input-set compiled opts failed]
  (loop [ns-info (.pollFirst deque)]
    (when (and ns-info (not (clojure.core/deref failed)))
      (let [{:keys [requires]} ns-info
            input-set' (clojure.core/deref input-set)
            {:keys [compiler-stats verbose]} opts]
        (if (every?
              (fn*
                [p1__12707#]
                (not (contains? input-set' p1__12707#)))
              requires)
          (do
            (try
              (swap!
                compiled
                conj
                (-compile
                  (or (:source-file ns-info) (:source-forms ns-info))
                  (merge
                    opts
                    {:output-file
                     (comp/rename-to-js
                       (util/ns->relpath (:ns ns-info)))})))
              (catch Throwable e (reset! failed e)))
            (when-not (clojure.core/deref failed)
              (when-let [ns (:ns ns-info)] (swap! input-set disj ns))
              (recur (.pollFirst deque))))
          (do (Thread/sleep 10) (recur ns-info)))))))
(defn compile
  "Given a Compilable, compile it and return an IJavaScript."
  [compilable opts]
  (-compile compilable opts))
(defn same-or-subdirectory-of?
  "Checks that path names a file or directory that is the dir or a subdirectory there of."
  [dir path]
  (let [dir-path (.getAbsolutePath (io/file dir))
        path-path (.getAbsolutePath (io/file path))]
    (.startsWith path-path dir-path)))
(defn get-compiled-cljs
  "Return an IJavaScript for this file. Compiled output will be\n   written to the working directory."
  [opts {:keys [relative-path uri]}]
  (let [js-file (comp/rename-to-js relative-path)
        compiled (-compile uri (merge opts {:output-file js-file}))]
    (add-core-macros-if-cljs-js compiled)))
(defn add-dependencies
  "DEPRECATED: Given one or more IJavaScript objects in dependency order, produce\n  a new sequence of IJavaScript objects which includes the input list\n  plus all dependencies in dependency order."
  [opts & inputs]
  (let [inputs (set inputs)
        requires (set (mapcat deps/-requires inputs))
        required-cljs (clojure.set/difference
                        (cljs-dependencies opts requires)
                        inputs)
        required-js (js-dependencies
                      opts
                      (into
                        (set (mapcat deps/-requires required-cljs))
                        requires))]
    (cons
      (javascript-file nil (io/resource "goog/base.js") ["goog"] nil)
      (deps/dependency-order
        (concat
          (map
            (fn [{:keys [type foreign url file provides requires] 
                  :as js-map}]
              (if (not= :seed type)
                (let [url (or url (io/resource file))]
                  (merge
                    (javascript-file foreign url provides requires)
                    js-map))
                js-map))
            required-js)
          (when (-> (clojure.core/deref env/*compiler*)
                 :options
                 :emit-constants)
            [(constants-javascript-file opts)])
          required-cljs
          inputs)))))
(defn source-for-namespace
  "Given a namespace and compilation environment return the relative path and\n  uri of the corresponding source regardless of the source language extension:\n  .cljs, .cljc, .js"
  [ns compiler-env]
  (let [ns-str (str (comp/munge ns {}))
        path (string/replace ns-str \. \/)
        relpath (str path ".cljs")]
    (if-let [cljs-res (io/resource relpath)]
      {:relative-path relpath  :uri cljs-res  :ext :cljs}
      (let [relpath (str path ".cljc")]
        (if-let [cljc-res (io/resource relpath)]
          {:relative-path relpath  :uri cljc-res  :ext :cljc}
          (let [relpath (str path ".js")]
            (if-let [js-res (io/resource relpath)]
              {:relative-path relpath  :uri js-res  :ext :js}
              (let [ijs (get-in
                          (clojure.core/deref compiler-env)
                          [:js-dependency-index (str ns)])
                    relpath (or (:file ijs) (:url ijs))]
                (if-let [js-res (and
                                  relpath
                                  (or
                                    (and (util/url? relpath) relpath)
                                    (try
                                      (URL. relpath)
                                      (catch Throwable t))
                                    (io/resource relpath)))]
                  {:relative-path relpath  :uri js-res  :ext :js}
                  (throw
                    (util/compilation-error
                      (IllegalArgumentException.
                        (str
                          "Namespace "
                          ns
                          " does not exist."
                          (when (string/includes? ns "-")
                            " Please check that namespaces with dashes use underscores in the ClojureScript file name."))))))))))))))
(defn compilable-input-paths
  "Takes a coll of inputs as strings or files and returns a\n  single Inputs and Compilable object."
  [paths]
  (reify
    cljs.closure/Inputs
    (-paths [_] (mapcat cljs.closure/-paths paths))
    cljs.closure/Compilable
    (-compile
      [_ opts]
      (mapcat
        (fn* [p1__12537#] (cljs.closure/-compile p1__12537# opts))
        paths))
    (-find-sources
      [_ opts]
      (mapcat
        (fn* [p1__12538#] (cljs.closure/-find-sources p1__12538# opts))
        paths))))
(defn check-unprovided [inputs]
  (let [requires (set (mapcat deps/-requires inputs))
        provided (set (mapcat deps/-provides inputs))
        unprovided (clojure.set/difference requires provided)]
    (when (seq unprovided)
      (ana/warning
        :unprovided
        (clojure.core/deref env/*compiler*)
        {:unprovided (sort unprovided)}))
    inputs))
(defn absolute-path? [path] (.isAbsolute (io/file path)))
(extend-protocol
  Inputs
  String
  (-paths [this] [(io/file this)])
  File
  (-paths [this] [this]))
(defn src-file->goog-require
  ([src] (src-file->goog-require src {:wrap true}))
  ([src {:keys [wrap all-provides macros-ns]  :as options}]
    (let [goog-ns (case
                    (util/ext src)
                    ("cljs" "cljc")
                    (let [ns-str (str
                                   (comp/munge
                                     (:ns (ana/parse-ns src))))]
                      (cond->
                        ns-str
                        (and
                          macros-ns
                          (not (.endsWith ns-str "$macros")))
                        (str "$macros")))
                    "js"
                    (cond->
                      (:provides (parse-js-ns src))
                      (not all-provides)
                      first)
                    (throw
                      (util/compilation-error
                        (IllegalArgumentException.
                          (str
                            "Can't create goog.require expression for "
                            src)))))]
      (if (and (not all-provides) wrap)
        (if (:reload options)
          (str "goog.require(\"" goog-ns "\", true);")
          (str "goog.require(\"" goog-ns "\");"))
        (if (vector? goog-ns) goog-ns (str goog-ns))))))
(defn compile-client-js [opts]
  (let [copts (select-keys
                opts
                [:optimizations :output-dir :language-in])]
    (build
      (quote
        [(ns clojure.browser.repl.client
           (:require [goog.events :as event]
                     [clojure.browser.repl :as repl]))
         (defn start [url]
           (event/listen
             js/window
             "load"
             (fn [] (repl/start-evaluator url))))])
      copts
      (env/default-compiler-env copts))))
(defn find-jar-sources [this opts] [(comp/find-source this)])
(defn cljs-dependencies
  "Given a list of all required namespaces, return a list of\n  IJavaScripts which are the cljs dependencies. The returned list will\n  not only include the explicitly required files but any transitive\n  dependencies as well. JavaScript files will be compiled to the\n  working directory if they do not already exist.\n\n  Only load dependencies from the classpath."
  [opts requires]
  (letfn
    [(cljs-deps
       [lib-names]
       (->>
         lib-names
         (remove
           (fn*
             [p1__12675#]
             (or
               (((clojure.core/deref env/*compiler*)
                  :js-dependency-index)
                 p1__12675#)
               (deps/find-classpath-lib p1__12675#))))
         (map cljs-source-for-namespace)
         (remove (comp nil? :uri))))]
    (loop [required-files (cljs-deps requires)
           visited (set required-files)
           js-deps #{}]
      (if (seq required-files)
        (let [next-file (first required-files)
              js (get-compiled-cljs opts next-file)
              new-req (remove
                        (fn*
                          [p1__12676#]
                          (contains? visited p1__12676#))
                        (cljs-deps (deps/-requires js)))]
          (recur
            (into (rest required-files) new-req)
            (into visited new-req)
            (conj js-deps js)))
        (disj js-deps nil)))))
(defn aot-cache-core []
  (let [base-path (io/file "src" "main" "cljs" "cljs")
        src (io/file base-path "core.cljs")
        dest (io/file base-path "core.aot.js")
        cache (io/file base-path "core.cljs.cache.aot.edn")
        tcache (io/file base-path "core.cljs.cache.aot.json")]
    (util/mkdirs dest)
    (env/with-compiler-env
      (env/default-compiler-env {:infer-externs true})
      (comp/compile-file
        src
        dest
        {:static-fns true 
         :source-map true 
         :source-map-url "core.js.map" 
         :output-dir
         (str "src" File/separator "main" File/separator "cljs")})
      (ana/write-analysis-cache (quote cljs.core) cache src)
      (ana/write-analysis-cache (quote cljs.core) tcache src))
    (create-client-js-file
      {:language-in :es6 
       :optimizations :simple 
       :output-dir "aot_out"}
      (io/file "resources" "brepl_client.js"))
    (doseq [f (file-seq (io/file "aot_out")) :when (.isFile f)]
      (.delete f))))
(defn- copy-from-cache [cache-path cacheable source-file opts]
  (doseq [[k f] cacheable]
    (when (.exists f)
      (let [target (io/file
                     (util/output-directory opts)
                     (-> (.getAbsolutePath f)
                      (string/replace (.getAbsolutePath cache-path) "")
                      (subs 1)))]
        (when (and
                (or ana/*verbose* (:verbose opts))
                (= :output-file k))
          (util/debug-prn (str "Copying cached " f " to " target)))
        (util/mkdirs target)
        (spit target (slurp f))
        (.setLastModified target (util/last-modified source-file))))))
(defn watch
  "Given a source directory, produce runnable JavaScript. Watch the source\n   directory for changes rebuilding when necessary. Takes the same arguments as\n   cljs.closure/build in addition to some watch-specific options:\n    - :watch-fn, a function of no arguments to run after a successful build. May\n                 be a function value or a namespaced symbol identifying a function,\n                 in which case the associated namespace willl be loaded and the\n                 symbol resolved.\n    - :watch-error-fn, a function receiving the exception of a failed build. May\n                       be a function value or a namespaced symbol, loaded as\n                       with :watch-fn."
  ([source opts]
    (watch
      source
      opts
      (if-not (nil? env/*compiler*)
        env/*compiler*
        (env/default-compiler-env opts))))
  ([source opts compiler-env] (watch source opts compiler-env nil))
  ([source opts compiler-env quit]
    (let [opts (cond->
                 opts
                 (= (:verbose opts :not-found) :not-found)
                 (assoc :verbose true))
          paths (map
                  (fn* [p1__13552#] (Paths/get (.toURI p1__13552#)))
                  (-paths source))
          path (first paths)
          fs (.getFileSystem path)
          srvc (.newWatchService fs)]
      (letfn
        [(buildf
           []
           (try
             (let [start (System/nanoTime)
                   watch-opts (assoc
                                opts
                                :cljs.closure/watch-triggered-build?
                                true)]
               (build source watch-opts compiler-env)
               (println
                 "... done. Elapsed"
                 (/ (unchecked-subtract (System/nanoTime) start) 1.0E9)
                 "seconds")
               (flush))
             (when-let [f (opts-fn :watch-fn opts)] (f))
             (catch
               Throwable
               e
               (if-let [f (opts-fn :watch-error-fn opts)]
                 (f e)
                 (binding [*out* *err*] (println e))))))
         (watch-all
           [root]
           (Files/walkFileTree
             root
             (reify
               FileVisitor
               (preVisitDirectory
                 [_ dir _]
                 (let [dir dir]
                   (. dir
                    (register
                      srvc
                      (into-array
                        [StandardWatchEventKinds/ENTRY_CREATE
                         StandardWatchEventKinds/ENTRY_DELETE
                         StandardWatchEventKinds/ENTRY_MODIFY])
                      (into-array
                        [SensitivityWatchEventModifier/HIGH]))))
                 FileVisitResult/CONTINUE)
               (postVisitDirectory
                 [_ dir exc]
                 FileVisitResult/CONTINUE)
               (visitFile [_ file attrs] FileVisitResult/CONTINUE)
               (visitFileFailed
                 [_ file exc]
                 FileVisitResult/CONTINUE))))]
        (println "Building ...")
        (flush)
        (buildf)
        (println "Watching paths:" (apply str (interpose ", " paths)))
        (doseq [path paths] (watch-all path))
        (loop [key nil]
          (when (and
                  (or (nil? quit) (not (clojure.core/deref quit)))
                  (or (nil? key) (. key reset)))
            (let [key (. srvc (poll 300 TimeUnit/MILLISECONDS))
                  poll-events-seq (when key (seq (.pollEvents key)))]
              (when (and
                      key
                      (some
                        (fn [e]
                          (let [fstr (.. e context toString)]
                            (and
                              (or
                                (. fstr (endsWith "cljc"))
                                (. fstr (endsWith "cljs"))
                                (. fstr (endsWith "clj"))
                                (. fstr (endsWith "js")))
                              (not (. fstr (startsWith ".#"))))))
                        poll-events-seq))
                (when-let [clj-files (seq
                                       (keep
                                         (fn 
                                           [e]
                                           (let 
                                             [ctx (.context e)
                                              fstr (.toString ctx)]
                                             (when
                                               (and
                                                 (or
                                                   (.
                                                    fstr
                                                    (endsWith "cljc"))
                                                   (.
                                                    fstr
                                                    (endsWith "clj")))
                                                 (not
                                                   (.
                                                    fstr
                                                    (startsWith
                                                      ".#"))))
                                               ctx)))
                                         poll-events-seq))]
                  (let [dir (.watchable key)
                        file-seq (map
                                   (fn*
                                     [p1__13553#]
                                     (.toFile
                                       (.resolve dir p1__13553#)))
                                   clj-files)
                        nses (map (comp :ns ana/parse-ns) file-seq)]
                    (doseq [ns nses] (require ns :reload))
                    (doseq [ns (cljs-dependents-for-macro-namespaces
                                 compiler-env
                                 nses)]
                      (mark-cljs-ns-for-recompile!
                        ns
                        (:output-dir opts)))))
                (println "Change detected, recompiling ...")
                (flush)
                (buildf))
              (recur key))))))))
(defn url->nio-path [url]
  (let [raw-uri (.toURI url)
        arr (-> raw-uri .toString (.split "!"))
        uri (-> arr (aget 0) URI/create)
        fs (try
             (FileSystems/getFileSystem uri)
             (catch
               Throwable
               t
               (FileSystems/newFileSystem uri (HashMap.))))]
    (.getPath fs (.toString raw-uri) (make-array String 0))))
(defn random-string [length]
  (apply str (take length (repeatedly random-char))))
(defn find-sources
  "Given a Compilable, find sources and return a sequence of IJavaScript."
  [compilable opts]
  (-find-sources compilable opts))
(defn in-same-dir?
  "Checks that path-1 and path-2 are siblings in the same logical directory."
  [path-1 path-2]
  (= (absolute-parent path-1) (absolute-parent path-2)))
(defn build-provides
  "Given a vector of provides, builds required goog.provide statements"
  [provides]
  (apply
    str
    (map
      (fn* [p1__12802#] (str "goog.provide('" p1__12802# "');\n"))
      provides)))
(defn compile-form-seq
  "Compile a sequence of forms to a JavaScript source string."
  ([forms]
    (compile-form-seq
      forms
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([forms opts]
    (comp/with-core-cljs
      opts
      (fn []
        (with-out-str
          (binding [ana/*cljs-ns* (quote cljs.user)]
            (doseq [form forms]
              (comp/emit (ana/analyze (ana/empty-env) form)))))))))
(defn compile-ns
  "Compiles a namespace and all of its transitive dependencies.\n   See compile-inputs."
  [ns opts]
  (compile-inputs (find-sources ns opts) opts))
(defn output-directory [opts] (util/output-directory opts))
(defn compile-inputs
  "Compile inputs and all of their transitive dependencies including JS modules,\n   libs, and foreign libs. Duplicates the pipeline of build."
  [inputs opts]
  (env/ensure
    (let [sources (-> inputs
                   ((fn*
                      [p1__13487#]
                      (map add-core-macros-if-cljs-js p1__13487#)))
                   (add-dependency-sources opts))
          opts (handle-js-modules opts sources env/*compiler*)
          sources (-> sources
                   deps/dependency-order
                   (compile-sources false opts)
                   (add-js-sources opts)
                   deps/dependency-order
                   (->>
                     (map
                       (fn*
                         [p1__13488#]
                         (source-on-disk opts p1__13488#)))
                     doall))]
      sources)))
(defn parse-js-ns [f] (deps/parse-js-ns (line-seq (io/reader f))))
(defn- gitlibs-cache-dir
  "Returns the gitlibs cache dir, a string."
  []
  (clojure.core/deref GITLIBS-CACHE-DIR))
(extend-protocol
  Compilable
  File
  (-compile
    [this opts]
    (if (.isDirectory this)
      (compile-dir this opts)
      (compile-file this opts)))
  (-find-sources
    [this _]
    (if (.isDirectory this)
      (comp/find-root-sources this)
      [(comp/find-source this)]))
  URL
  (-compile
    [this opts]
    (case
      (.getProtocol this)
      "file"
      (-compile (io/file this) opts)
      "jar"
      (compile-from-jar this opts)))
  (-find-sources
    [this opts]
    (case
      (.getProtocol this)
      "file"
      (-find-sources (io/file this) opts)
      "jar"
      (find-jar-sources this opts)))
  clojure.lang.PersistentList
  (-compile [this opts] (compile-form-seq [this]))
  (-find-sources [this opts] [(ana/parse-ns [this] opts)])
  String
  (-compile [this opts] (-compile (io/file this) opts))
  (-find-sources [this opts] (-find-sources (io/file this) opts))
  clojure.lang.Symbol
  (-compile [this opts] (-compile (util/ns->source this) opts))
  (-find-sources
    [this opts]
    (-find-sources (util/ns->source this) opts))
  clojure.lang.PersistentVector
  (-compile [this opts] (compile-form-seq this))
  (-find-sources [this opts] [(ana/parse-ns this opts)])
  clojure.lang.IPersistentSet
  (-compile
    [this opts]
    (doall
      (map
        (comp
          (fn* [p1__12600#] (-compile p1__12600# opts))
          util/ns->source)
        this)))
  (-find-sources
    [this opts]
    (into
      []
      (mapcat (fn* [p1__12601#] (-find-sources p1__12601# opts)))
      this)))
(defn random-char []
  (nth name-chars (.nextInt (Random.) (count name-chars))))
(defn read-js
  "Read a JavaScript file returning a map of file information."
  [f]
  (let [source (slurp f)
        m (deps/parse-js-ns (string/split-lines source))]
    (map->javascript-file (assoc m :file f))))
(defn- gitlibs-src?
  "Returns true if the file comes from the gitlibs cache."
  [file]
  false)
(defn compile-dir
  "Recursively compile all cljs files under the given source\n  directory. Return a list of JavaScriptFiles."
  [src-dir opts]
  (let [out-dir (util/output-directory opts)]
    (map compiled-file (comp/compile-root src-dir out-dir opts))))
(defn src-file->target-file
  ([src]
    (src-file->target-file
      src
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src opts]
    (util/to-target-file
      (when (:output-dir opts) (util/output-directory opts))
      (ana/parse-ns src))))
(defn mark-cljs-ns-for-recompile! [ns-sym output-dir]
  (let [s (target-file-for-cljs-ns ns-sym output-dir)]
    (when (.exists s) (.setLastModified s 5000))))
(defn create-client-js-file [opts file-path]
  (if-let [cached (io/resource "brepl_client.js")]
    cached
    (let [file (io/file file-path)]
      (when (not (.exists file)) (spit file (compile-client-js opts)))
      file)))
cljs.analyzer.impl.namespaces 107/107 (100.0%)
(defn elide-aliases-from-libspecs
  "Given libspecs, elide all :as-alias. Return a map of :libspecs (filtered)\n   and :as-aliases."
  ([libspecs] (elide-aliases-from-libspecs libspecs {}))
  ([libspecs as-aliases]
    (let [ret {:as-aliases as-aliases  :libspecs []}]
      (reduce
        (fn [ret libspec]
          (let [{:keys [as-alias libspec]} (check-and-remove-as-alias
                                             libspec)]
            (check-as-alias-duplicates (:as-aliases ret) as-alias)
            (cond->
              ret
              libspec
              (update :libspecs conj libspec)
              as-alias
              (update :as-aliases merge as-alias))))
        ret
        libspecs))))
(defn check-and-remove-as-alias
  "Given a libspec return a map of :as-alias alias, if was present. Return the\n   libspec with :as-alias elided. If the libspec was *only* :as-alias do not\n   return it."
  [libspec]
  (if (or (symbol? libspec) (keyword? libspec))
    {:libspec libspec}
    (let [[lib & spec :as libspec] libspec
          [pre-spec [_ alias & post-spec :as post]] (split-with
                                                      (complement
                                                        #{:as-alias})
                                                      spec)]
      (if (seq post)
        (let [libspec' (into [lib] (concat pre-spec post-spec))]
          (assert
            (symbol? alias)
            (str
              ":as-alias must be followed by a symbol, got: "
              alias))
          (cond->
            {:as-alias {alias lib}}
            (> (count libspec') 1)
            (assoc :libspec libspec')))
        {:libspec libspec}))))
(defn check-as-alias-duplicates [as-aliases new-as-aliases]
  (doseq [[alias _] new-as-aliases]
    (assert
      (not (contains? as-aliases alias))
      (str
        "Duplicate :as-alias "
        alias
        ", already in use for lib "
        (get as-aliases alias)))))
(defn elide-aliases-from-ns-specs [ns-specs]
  "Given ns specs, elide all :as-alias. Return a map of :libspecs (filtered)\n   and :as-aliases."
  (let [ret {:as-aliases {}  :libspecs []}]
    (reduce
      (fn [{:keys [as-aliases]  :as ret} [spec-key & libspecs]]
        (if-not (= :refer-clojure spec-key)
          (let [{:keys [as-aliases libspecs]} (elide-aliases-from-libspecs
                                                libspecs
                                                as-aliases)]
            (cond->
              ret
              (not (empty? as-aliases))
              (update :as-aliases merge as-aliases)
              (not (empty? libspecs))
              (update :libspecs conj (list* spec-key libspecs))))
          (update ret :libspecs conj (list* spec-key libspecs))))
      ret
      ns-specs)))
cljs.compiler-tests 70/75 (93.3%)
(clojure.core/defn capture-warnings
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list
          (quote cljs.compiler-tests/capture-warnings*))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq (clojure.core/concat))))
              body)))))))
(defn compile-form-seq
  ([forms]
    (compile-form-seq
      forms
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([forms opts]
    (with-out-str
      (binding [ana/*cljs-ns* (quote cljs.user)]
        (doseq [form forms]
          (comp/emit (ana/analyze (ana/empty-env) form)))))))
(defn capture-warnings* [f]
  (let [capture (atom [])
        tracker (fn [warning-type env & [extra]]
                  (when (warning-type ana/*cljs-warnings*)
                    (let [err (ana/error-message warning-type extra)
                          msg (ana/message env (str "WARNING: " err))]
                      (swap! capture conj [warning-type msg]))))]
    (ana/with-warning-handlers [tracker] (f))
    (clojure.core/deref capture)))
(defn emit [ast] (env/ensure (comp/emit ast)))
(defn analyze
  ([env form] (env/ensure (ana/analyze env form)))
  ([env form name] (env/ensure (ana/analyze env form name)))
  ([env form name opts] (env/ensure (ana/analyze env form name opts))))
cljs.js-deps 492/540 (91.1%)
(defn dependency-order-visit
  ([state ns-name] (dependency-order-visit state ns-name []))
  ([state ns-name seen]
    (if-not (some #{ns-name} seen)
      (let [file (get state ns-name)]
        (if (or (:visited file) (nil? file))
          state
          (let [state (assoc-in state [ns-name :visited] true)
                deps (:requires file)
                state (reduce
                        (fn*
                          [p1__1331# p2__1332#]
                          (dependency-order-visit
                            p1__1331#
                            p2__1332#
                            (conj seen ns-name)))
                        state
                        deps)]
            (assoc state :order (conj (:order state) file)))))
      state)))
(defn- library-graph-node
  "Returns a map of :provides, :requires, and :url given a URL to a goog-style\nJavaScript library containing provide/require 'declarations'."
  ([url] (library-graph-node url nil))
  ([url lib-path]
    (with-open [reader (io/reader url)]
      (-> reader
       line-seq
       parse-js-ns
       (merge
         {:url url}
         (when lib-path {:closure-lib true  :lib-path lib-path}))))))
(defn find-js-fs
  "finds js resources from a path on the files system"
  [path]
  (let [file (io/file path)]
    (when (.exists file)
      (map
        to-url
        (filter
          (fn* [p1__1137#] (.endsWith (.getName p1__1137#) ".js"))
          (file-seq (io/file path)))))))
(defn jar-entry-names* [jar-path]
  (when-let [zf (zip-file jar-path)]
    (with-open [z zf]
      (doall
        (map
          (fn* [p1__1111#] (.getName p1__1111#))
          (enumeration-seq (.entries z)))))))
(defn goog-dependencies*
  "Create an index of Google dependencies by namespace and file name from\n  goog/deps.js"
  []
  (letfn
    [(parse-list
       [s]
       (when (> (count s) 0)
         (-> (.substring s 1 (dec (count s)))
          (string/split #"'\s*,\s*'"))))]
    (with-open [reader (io/reader (io/resource "goog/deps.js"))]
      (->>
        (line-seq reader)
        (map
          (fn*
            [p1__1365#]
            (re-matches
              #"^goog\.addDependency\(['\"](.*)['\"],\s*\[(.*)\],\s*\[(.*)\],\s*(\{.*\})\);.*"
              p1__1365#)))
        (remove nil?)
        (map (fn* [p1__1366#] (drop 1 p1__1366#)))
        (remove
          (fn*
            [p1__1367#]
            (.startsWith (first p1__1367#) "../../third_party")))
        (map
          (fn [[file provides requires load-opts-str]]
            (let [{:strs [lang module]} (->
                                         (string/replace
                                           load-opts-str
                                           "'"
                                           "\"")
                                         (json/read-str))
                  file' (str "goog/" file)]
              (merge
                {:file file' 
                 :provides (parse-list provides) 
                 :requires (parse-list requires) 
                 :require-types
                 (-> file'
                  io/resource
                  io/reader
                  line-seq
                  parse-js-ns
                  :require-types) 
                 :group :goog}
                (when module {:module (keyword module)})
                (when lang {:lang (keyword lang)})))))
        (doall)))))
(defn find-js-classpath
  "Returns a seq of URLs of all JavaScript files on the classpath."
  [path]
  (->>
    (classpath-files)
    (reduce
      (fn [files jar-or-dir]
        (let [name (.toLowerCase (.getName jar-or-dir))
              ext (.substring name (inc (.lastIndexOf name ".")))]
          (->>
            (when (.exists jar-or-dir)
              (cond
                (.isDirectory jar-or-dir) (find-js-fs
                                            (str
                                              (.getAbsolutePath
                                                jar-or-dir)
                                              "/"
                                              path))
                (#{"jar" "zip"} ext) (find-js-jar jar-or-dir path)
                :else nil))
            (remove nil?)
            (into files))))
      [])))
(defn- unpack-string [m] (or (:cljs.js-deps/original m) m))
(defn dependency-order
  "Topologically sort a collection of dependencies."
  [coll]
  (let [state (build-index (map pack-string coll))]
    (map
      unpack-string
      (distinct-by
        :provides
        (:order
          (reduce
            dependency-order-visit
            (assoc state :order [])
            (keys state)))))))
(defn parse-js-ns
  "Given the lines from a JavaScript source file, parse the provide\n  and require statements and return them in a map. Assumes that all\n  provide and require statements appear before the first function\n  definition."
  [lines]
  (letfn
    [(conj-in [m k v] (update-in m [k] (fn [old] (conj old v))))]
    (->>
      (for [line lines x (string/split line #";")] x)
      (map string/trim)
      (drop-while
        (fn*
          [p1__1145#]
          (not
            (or
              (string/includes? p1__1145# "goog.provide(")
              (string/includes? p1__1145# "goog.module(")
              (string/includes? p1__1145# "goog.require(")
              (string/includes? p1__1145# "goog.requireType(")))))
      (take-while
        (fn*
          [p1__1146#]
          (not
            (re-matches
              #".*=[\s]*function\(.*\)[\s]*[{].*"
              p1__1146#))))
      (map
        (fn*
          [p1__1147#]
          (re-matches
            #".*goog\.(provide|module|require|requireType)\(['\"](.*)['\"]\)"
            p1__1147#)))
      (remove nil?)
      (map (fn* [p1__1148#] (drop 1 p1__1148#)))
      (reduce
        (fn [m ns]
          (let [munged-ns (string/replace (last ns) "_" "-")]
            (case
              (first ns)
              "provide"
              (conj-in m :provides munged-ns)
              "module"
              (-> m
               (conj-in :provides munged-ns)
               (assoc :module :goog))
              "require"
              (conj-in m :requires munged-ns)
              "requireType"
              (conj-in m :require-types munged-ns))))
        {:requires []  :provides []  :require-types []}))))
(defn lib-spec-merge [a b]
  (merge a (cond-> b (contains? a :provides) (dissoc :provides))))
(defn load-library*
  "Given a path to a JavaScript library, which is a directory\n  containing Javascript files, return a list of maps\n  containing :provides, :requires, :file and :url."
  [path]
  (->>
    (find-js-resources path)
    (map (fn* [p1__1349#] (library-graph-node p1__1349# path)))
    (filter (fn* [p1__1350#] (seq (:provides p1__1350#))))))
(defn library-dependencies [{libs :libs 
                             foreign-libs :foreign-libs 
                             ups-libs :ups-libs 
                             ups-flibs :ups-foreign-libs}]
  (concat
    (mapcat load-library ups-libs)
    (mapcat
      load-library
      (filter (fn* [p1__1356#] (.exists (io/file p1__1356#))) libs))
    (map
      (fn* [p1__1357#] (load-foreign-library p1__1357# true))
      ups-flibs)
    (map load-foreign-library foreign-libs)))
(defmethod to-url File [f] (.toURL (.toURI f)))
(defn load-foreign-library*
  "Given a library spec (a map containing the keys :file\n  and :provides), returns a map containing :provides, :requires, :file\n  and :url"
  ([lib-spec] (load-foreign-library* lib-spec false))
  ([lib-spec cp-only?]
    (let [find-func (if cp-only? io/resource find-url)]
      (cond->
        (assoc lib-spec :foreign true)
        (:file lib-spec)
        (assoc :url (find-func (:file lib-spec)))
        (:file-min lib-spec)
        (assoc :url-min (find-func (:file-min lib-spec)))))))
(defn find-js-jar
  "Returns a seq of URLs of all JavaScript resources in the given jar"
  [jar-path lib-path]
  (map
    io/resource
    (filter
      (fn*
        [p1__1116#]
        (and
          (.endsWith p1__1116# ".js")
          (.startsWith p1__1116# lib-path)))
      (jar-entry-names jar-path))))
(defn js-dependency-index
  "Returns the index for all JavaScript dependencies. Lookup by\n  namespace or file name."
  [opts]
  (build-index
    (concat (library-dependencies opts) (goog-dependencies))))
(defmethod to-url String [s] (to-url (io/file s)))
(defn build-index
  "Index a list of dependencies by namespace and file name. There can\n  be zero or more namespaces provided per file. Upstream foreign libraies\n  will have their options merged with local foreign libraries to support\n  fine-grained overriding."
  [deps]
  (reduce
    (fn [index dep]
      (let [provides (:provides dep)
            index' (if (seq provides)
                     (reduce
                       (fn [index' provide]
                         (if (:foreign dep)
                           (update-in
                             index'
                             [provide]
                             lib-spec-merge
                             dep)
                           (let [file
                                 (when-let 
                                   [f
                                    (or
                                      (:source-file dep)
                                      (:file dep))]
                                   (str f))
                                 ext
                                 (when
                                   file
                                   (subs
                                     file
                                     (inc
                                       (string/last-index-of
                                         file
                                         "."))))]
                             (update-in
                               index'
                               [provide]
                               (fn 
                                 [d]
                                 (if
                                   (and (= ext "cljc") (some? d))
                                   d
                                   dep))))))
                       index
                       provides)
                     index)]
        (if (:foreign dep)
          (if-let [file (get-file dep index')]
            (update-in index' [file] lib-spec-merge dep)
            (throw
              (util/compilation-error
                (Exception.
                  (str
                    "No :file provided for :foreign-libs spec "
                    (pr-str dep))))))
          (assoc index' (:file dep) dep))))
    {}
    deps))
(defn find-url
  "Given a string, returns a URL. Attempts to resolve as a classpath-relative\n  path, then as a path relative to the working directory or a URL string"
  [path-or-url]
  (or
    (io/resource path-or-url)
    (try
      (io/as-url path-or-url)
      (catch java.net.MalformedURLException e false))
    (io/as-url (io/as-file path-or-url))))
(defn find-js-resources [path]
  "Returns a seq of URLs to all JavaScript resources on the classpath or within\na given (directory) path on the filesystem. [path] only applies to the latter\ncase."
  (let [file (io/file path)]
    (if (.exists file) (find-js-fs path) (find-js-classpath path))))
(defn find-classpath-lib
  "Given [lib], a string or symbol naming a goog-style JavaScript library\n  (i.e. one that uses goog.provide and goog.require), look for a resource on the\n  classpath corresponding to [lib] and return a map via `library-graph-node`\n  that contains its relevant metadata.  The library found on the classpath\n  _must_ contain a `goog.provide` that matches [lib], or this fn will return nil\n  and print a warning."
  [lib]
  (when-let [lib-resource (some->
                            (name lib)
                            (.replace \. \/)
                            (.replace \- \_)
                            (str ".js")
                            io/resource)]
    (let [{:keys [provides]  :as lib-info} (library-graph-node
                                             lib-resource)]
      (if (some #{(name lib)} provides)
        (assoc lib-info :closure-lib true)
        (binding [*out* *err*]
          (println
            (format
              (str
                "WARNING: JavaScript file found on classpath for library `%s`, "
                "but does not contain a corresponding `goog.provide` declaration: %s")
              lib
              lib-resource)))))))
(defn zip-file [jar-path]
  (try
    (cond
      (instance? File jar-path) (ZipFile. jar-path)
      (string? jar-path) (ZipFile. jar-path))
    (catch Exception _ nil)))
(defmethod to-url URL [url] url)
(defn- pack-string [s]
  (if (string? s)
    {:provides (-provides s) 
     :requires (-requires s) 
     :file (str "from_source_" (gensym) ".clj") 
     :cljs.js-deps/original s}
    s))
(defn get-file [lib-spec index]
  (or
    (:file lib-spec)
    (some
      (fn [provide] (get-in index [provide :file]))
      (:provides lib-spec))))
(defn- classpath-files
  "Returns a list of classpath files. Under Java 8, walks up the parentage\n  chain of RT/baseLoader, concatenating any URLs it retrieves. Under Java 9 and\n  later, builds file list from the java.class.path system property."
  []
  (->>
    (if java-8?
      (->>
        (clojure.lang.RT/baseLoader)
        (iterate (fn* [p1__1103#] (.getParent p1__1103#)))
        (take-while identity)
        reverse
        (filter (partial instance? URLClassLoader))
        (mapcat (fn* [p1__1104#] (.getURLs p1__1104#))))
      (-> (System/getProperty "java.class.path") util/split-paths))
    distinct
    (map io/file)))
cljs.externs 503/510 (98.6%)
(defn params->method-params [xs]
  (letfn
    [(not-opt? [x] (not (string/starts-with? (name x) "opt_")))]
    (let [required (into [] (take-while not-opt? xs))
          opts (drop-while not-opt? xs)]
      (loop [ret [required] opts opts]
        (if-let [opt (first opts)]
          (recur (conj ret (conj (last ret) opt)) (drop 1 opts))
          (seq ret))))))
(defn gtype->cljs-type [t]
  (when t
    (cond
      (generic? t) (quote any)
      (= t (quote Array)) (quote array)
      :else t)))
(defn get-tag [texpr]
  (when-let [root (.getRoot texpr)]
    (if (.isString root)
      (symbol (.getString root))
      (if-let [child (.. root getFirstChild)]
        (if (.isString child) (symbol (.. child getString)))))))
(defn resource->source-file [resource]
  (-> (SourceFile/builder)
   (.withPath (.getPath resource))
   (.withContent (io/input-stream resource))
   (.build)))
(defn index-externs [externs]
  (reduce
    (fn [m xs] (cond-> m (seq xs) (update-in xs merge {})))
    {}
    externs))
(defmethod
  parse-extern-node
  Token/GETPROP
  [node]
  (when-not *ignore-var*
    (let [props (map
                  symbol
                  (string/split (.getQualifiedName node) #"\."))]
      [(if-let [ty (get-var-info node)] (annotate props ty) props)])))
(defn get-var-info [node]
  (when node
    (let [info (.getJSDocInfo node)]
      (when info
        (merge
          (if-let [ty (.getType info)]
            {:tag (get-tag ty)}
            (if (or (.isConstructor info) (.isInterface info))
              (let [qname (symbol
                            (.. node getFirstChild getQualifiedName))]
                (cond->
                  {:tag (quote Function)}
                  (.isConstructor info)
                  (merge {:ctor qname})
                  (.isInterface info)
                  (merge {:iface qname})))
              (if (or
                    (.hasReturnType info)
                    (as->
                      (.getParameterCount info)
                      c
                      (and c (pos? c))))
                (let [arglist (into
                                []
                                (map symbol (.getParameterNames info)))
                      arglists (params->method-params arglist)]
                  {:tag (quote Function) 
                   :js-fn-var true 
                   :ret-tag
                   (or
                     (some->
                       (.getReturnType info)
                       get-tag
                       gtype->cljs-type)
                     (quote clj-nil)) 
                   :variadic?
                   (boolean (some (quote #{var_args}) arglist)) 
                   :max-fixed-arity
                   (count
                     (take-while
                       (fn*
                         [p1__1411#]
                         (not= (quote var_args) p1__1411#))
                       arglist)) 
                   :method-params arglists 
                   :arglists arglists}))))
          {:file *source-file*  :line (.getLineno node)}
          (when-let [doc (.getOriginalCommentString info)] {:doc doc})
          (when (= JSDocInfo$Visibility/PRIVATE (.getVisibility info))
            {:private true}))))))
(defn ns-match? [ns-segs var-segs]
  (or
    (= ns-segs var-segs)
    (and
      (= (inc (count ns-segs)) (count var-segs))
      (= ns-segs (take (count ns-segs) var-segs)))))
(defmethod
  parse-extern-node
  Token/VAR
  [node]
  (when (> (.getChildCount node) 0)
    (let [ty (get-var-info node)]
      (cond->
        (parse-extern-node (.getFirstChild node))
        ty
        (-> first (annotate ty) vector)))))
(defmethod parse-extern-node :default [node])
(defmethod
  parsed->defs
  :goog
  ([externs _]
    (let [grouped (group-by
                    (fn*
                      [p1__1500#]
                      (= (quote exports) (first p1__1500#)))
                    externs)
          exports (->>
                    (get grouped true)
                    (map (comp vec rest))
                    (remove empty?)
                    set)
          exported (filter exports (get grouped false))]
      (reduce
        (fn [m xs]
          (let [sym (last xs)]
            (cond->
              m
              (seq xs)
              (assoc
                sym
                (merge (meta sym) {:ns *goog-ns*  :name sym})))))
        {}
        exported))))
(defn generic? [t] (let [s (name t)] (boolean (re-matches #"[A-Z]" s))))
(defmethod
  parse-extern-node
  Token/FUNCTION
  [node]
  (when (> (.getChildCount node) 0)
    (let [ty (get-var-info node)]
      (doto
        (cond->
          (parse-extern-node (.getFirstChild node))
          ty
          (-> first (annotate ty) vector))))))
(defn analyze-goog-file
  ([f] (analyze-goog-file f nil))
  ([f ns]
    (let [rsrc (io/resource f)
          desc (js-deps/parse-js-ns (line-seq (io/reader rsrc)))
          ns (or ns (-> (:provides desc) first symbol))]
      (binding [*goog-ns* ns]
        {:name ns 
         :defs
         (parsed->defs
           (parse-externs (resource->source-file rsrc))
           (:module desc))}))))
(defmethod
  parse-extern-node
  Token/OBJECTLIT
  [node]
  (when (> (.getChildCount node) 0)
    (loop [nodes (.children node) externs []]
      (if (empty? nodes)
        externs
        (recur
          (rest nodes)
          (concat externs (parse-extern-node (first nodes))))))))
(defn annotate
  "Given a sequential list of properties [foo core baz] representing segments\n  of the namespace, annotate the last symbol with the type information."
  [props ty]
  (when (seq props)
    (conj (into [] (butlast props)) (with-meta (last props) ty))))
(defmethod
  parsed->defs
  :default
  ([externs _]
    (let [ns-segs (into
                    []
                    (map symbol (string/split (str *goog-ns*) #"\.")))]
      (reduce
        (fn [m xs]
          (if (ns-match? ns-segs xs)
            (let [sym (last xs)]
              (cond->
                m
                (seq xs)
                (assoc
                  sym
                  (merge (meta sym) {:ns *goog-ns*  :name sym}))))
            m))
        {}
        externs))))
(defmethod
  parse-extern-node
  Token/NAME
  [node]
  (if (= Token/STRING_KEY (-> node .getParent .getToken))
    []
    (let [name (or (.getQualifiedName node) (.getString node))
          lhs (when-not (string/blank? name)
                (map symbol (string/split name #"\.")))]
      (if (seq lhs)
        (if (> (.getChildCount node) 0)
          (let [externs (parse-extern-node (.getFirstChild node))]
            (conj (map (fn [ext] (concat lhs ext)) externs) lhs))
          [lhs])
        []))))
(defn externs-map*
  ([] (externs-map* (CommandLineRunner/getDefaultExterns)))
  ([sources]
    (externs-map*
      sources
      (quote
        {eval {} 
         global {} 
         goog {nodeGlobalRequire {}} 
         COMPILED {} 
         TypeError {} 
         Error {prototype {number {}  columnNumber {}}} 
         ReferenceError {}})))
  ([sources defaults]
    (let [sources (if-not (empty? sources)
                    sources
                    (CommandLineRunner/getDefaultExterns))]
      (reduce
        (fn [externs externs-file]
          (util/map-merge
            externs
            (index-externs (parse-externs externs-file))))
        defaults
        sources))))
(defmethod
  parse-extern-node
  Token/EXPR_RESULT
  [node]
  (when (> (.getChildCount node) 0)
    (parse-extern-node (.getFirstChild node))))
(defn parse-externs
  "Returns a sequential collection of the form:\n\n    [[foo core first]\n     [foo core next]\n     [foo core baz last] ...]\n\n  Where the last symbol is annotated with var info via metadata. This simple\n  structure captures the nested form of Closure namespaces and aids\n  direct indexing."
  [source-file]
  (binding [*source-file* (.getName source-file)]
    (let [compiler-options (doto
                             (CompilerOptions.)
                             (.setParseJsDocDocumentation
                               Config$JsDocParsing/INCLUDE_DESCRIPTIONS_WITH_WHITESPACE))
          closure-compiler (doto
                             (let [compiler
                                   (com.google.javascript.jscomp.Compiler.)]
                               (com.google.javascript.jscomp.Compiler/setLoggingLevel
                                 Level/WARNING)
                               compiler)
                             (.init
                               (list source-file)
                               (quote ())
                               compiler-options))
          js-ast (JsAst. source-file)
          root (.getAstRoot js-ast closure-compiler)
          nodes (.children root)]
      (loop [nodes (cond->
                     nodes
                     (=
                       Token/MODULE_BODY
                       (some-> nodes first .getToken))
                     (-> first .children))
             externs []]
        (if (empty? nodes)
          externs
          (let [node (first nodes) new-extern (parse-extern-node node)]
            (recur (rest nodes) (concat externs new-extern))))))))
(defmethod
  parse-extern-node
  Token/ASSIGN
  [node]
  (when (> (.getChildCount node) 0)
    (let [ty (get-var-info node)
          lhs (cond->
                (first (parse-extern-node (.getFirstChild node)))
                ty
                (annotate ty))]
      (if (> (.getChildCount node) 1)
        (let [externs (binding [*ignore-var* true]
                        (parse-extern-node (.getChildAtIndex node 1)))]
          (conj (map (fn [ext] (concat lhs ext)) externs) lhs))
        [lhs]))))
(defmethod
  parse-extern-node
  Token/STRING_KEY
  [node]
  (let [lhs [(-> node .getString symbol)]]
    (if (> (.getChildCount node) 0)
      (let [externs (parse-extern-node (.getFirstChild node))]
        (conj (map (fn [ext] (concat lhs ext)) externs) lhs))
      [lhs])))
cljs.tagged-literals 26/45 (57.8%)
(defn valid-js-literal-key? [k]
  (or (string? k) (and (keyword? k) (nil? (namespace k)))))
(deftype JSValue [val])
(defn read-js [form]
  (when-not (or (vector? form) (map? form))
    (throw
      (RuntimeException.
        "JavaScript literal must use map or vector notation")))
  (when-not (or
              (not (map? form))
              (every? valid-js-literal-key? (keys form)))
    (throw
      (RuntimeException.
        "JavaScript literal keys must be strings or unqualified keywords")))
  (JSValue. form))
(defn read-uuid [form]
  (when-not (string? form)
    (throw
      (RuntimeException.
        "UUID literal expects a string as its representation.")))
  (try
    (java.util.UUID/fromString form)
    (catch Throwable e (throw (RuntimeException. (.getMessage e))))))
(defn read-queue [form]
  (when-not (vector? form)
    (throw
      (RuntimeException.
        "Queue literal expects a vector for its elements.")))
  (list
    (quote cljs.core/into)
    (quote cljs.core.PersistentQueue.EMPTY)
    form))
(defn read-inst [form]
  (when-not (string? form)
    (throw
      (RuntimeException.
        "Instance literal expects a string for its timestamp.")))
  (try
    (inst/read-instant-instant form)
    (catch Throwable e (throw (RuntimeException. (.getMessage e))))))
cljs.test-runner 3/3 (100.0%)
(defn -main []
  (let [{:keys [fail error]} (run-tests
                               (quote cljs.analyzer-api-tests)
                               (quote cljs.analyzer.as-alias-test)
                               (quote cljs.analyzer-pass-tests)
                               (quote cljs.analyzer-tests)
                               (quote cljs.build-api-tests)
                               (quote cljs.closure-tests)
                               (quote cljs.compiler-tests)
                               (quote cljs.compiler.glib-module-test)
                               (quote cljs.externs-infer-tests)
                               (quote cljs.externs-parsing-tests)
                               (quote cljs.instant-tests)
                               (quote cljs.js-deps-tests)
                               (quote cljs.module-graph-tests)
                               (quote cljs.module-processing-tests)
                               (quote cljs.source-map.base64-tests)
                               (quote cljs.transpile-tests)
                               (quote cljs.type-inference-tests)
                               (quote cljs.util-tests))]
    ))
cljs.module-processing-tests 60/60 (100.0%)
(defn preprocess-jsx [ijs _]
  (assoc
    ijs
    :source
    (clojure.string/replace
      (:source ijs)
      (re-pattern
        (str
          "\\(\\R"
          "\\s*\\R"
          "\\s*\\R"
          "\\s*\\R"
          "\\s*\\R"
          "\\s*\\)"))
      (str
        " React.createElement(\"svg\", {width:\"200px\", height:\"200px\", className:\"center\"}, "
        "React.createElement(\"circle\", {cx:\"100px\", cy:\"100px\", r:\"100px\", fill:this.props.color})"
        ")"))))
(defmethod
  closure/js-transforms
  :jsx
  [ijs opts]
  (preprocess-jsx ijs opts))
(defn absolute-module-path
  ([relpath] (absolute-module-path relpath false))
  ([relpath code?]
    (let [filename (as->
                     (subs relpath (inc (.lastIndexOf relpath "/")))
                     $
                     (string/replace $ "_" "-")
                     (subs $ 0 (.lastIndexOf $ ".")))
          dirname (as->
                    (io/file relpath)
                    $
                    (.getAbsolutePath $)
                    (subs $ 0 (.lastIndexOf $ (str File/separator)))
                    (string/replace $ "/" "$")
                    (string/replace $ \. \-)
                    (cond-> $ code? (string/replace "-" "_"))
                    (string/replace $ "\\" "$")
                    (if code?
                      (string/replace $ ":" "_")
                      (string/replace $ ":" "-")))]
      (str
        "module"
        (when-not (.startsWith dirname "$") "$")
        dirname
        "$"
        filename))))
cljs.compiler 3019/3622 (83.4%)
(defn safe-test? [env e]
  (let [tag (ana/infer-tag env e)]
    (or (#{(quote seq) (quote boolean)} tag) (truthy-constant? e))))
(defn protocol-prefix [psym]
  (symbol (str (-> (str psym) (.replace \. \$) (.replace \/ \$)) "$")))
(defn- wrap-in-double-quotes [x] (str \" x \"))
(defmethod
  emit*
  :ns
  [{:keys [name requires uses require-macros reloads env deps]}]
  (emitln "goog.provide('" (munge name) "');")
  (when-not (= name (quote cljs.core))
    (emitln "goog.require('cljs.core');")
    (when (-> (clojure.core/deref env/*compiler*)
           :options
           :emit-constants)
      (emitln "goog.require('" (munge ana/constants-ns-sym) "');")))
  (load-libs requires nil (:require reloads) deps name)
  (load-libs uses requires (:use reloads) deps name))
(defmethod
  emit*
  :set
  [{:keys [items env]}]
  (emit-wrap env (emit-set items comma-sep distinct-constants?)))
(defn emits-keyword [kw]
  (let [ns (namespace kw) name (name kw)]
    (emits "new cljs.core.Keyword(")
    (emit-constant ns)
    (emits ",")
    (emit-constant name)
    (emits ",")
    (emit-constant (if ns (str ns "/" name) name))
    (emits ",")
    (emit-constant (hash kw))
    (emits ")")))
(defn distinct-constants? [items]
  (let [items (map ana/unwrap-quote items)]
    (and
      (every? (fn* [p1__5365#] (= (:op p1__5365#) :const)) items)
      (= (count (into #{} items)) (count items)))))
(defmethod emit-constant* Boolean [x] (emits (if x "true" "false")))
(defn emit-global-export [ns-name global-exports lib]
  (let [[lib' sublib] (ana/lib&sublib lib)]
    (emitln
      (munge ns-name)
      "."
      (ana/munge-global-export lib)
      " = goog.global"
      (->>
        (string/split
          (name
            (or
              (get global-exports (symbol lib'))
              (get global-exports (name lib'))))
          #"\.")
        (map (fn [prop] (str "[\"" prop "\"]")))
        (apply str))
      (sublib-select sublib)
      ";")))
(defmethod emit* :no-op [m])
(defmethod emit* :host-call [ast] (emit-dot ast))
(defn emit-constants-table-to-file [table dest]
  (io/make-parents dest)
  (with-open [out (io/make-writer dest {})]
    (binding [*out* out] (emit-constants-table table))))
(defn emit-inferred-externs-to-file [externs dest]
  (io/make-parents dest)
  (with-open [out (io/make-writer dest {})]
    (binding [*out* out] (emit-externs externs))))
(defmethod emit* :quote [{:keys [expr]}] (emit expr))
(defmethod
  emit*
  :the-var
  [{:keys [env var sym meta]  :as arg}]
  {:pre [(ana/ast? sym) (ana/ast? meta)]}
  (let [{:keys [name]} (:info var)]
    (emit-wrap
      env
      (emits
        "new cljs.core.Var(function(){return "
        (munge name)
        ";},"
        sym
        ","
        meta
        ")"))))
(defmethod
  emit*
  :js-array
  [{:keys [items env]}]
  (emit-wrap env (emit-js-array items comma-sep)))
(defmethod emit* :var [expr] (emit-var expr))
(defmethod
  emit*
  :recur
  [{:keys [frame exprs env]}]
  (let [temps (vec (take (count exprs) (repeatedly gensym)))
        params (:params frame)]
    (dotimes [i (count exprs)]
      (emitln "var " (temps i) " = " (exprs i) ";"))
    (dotimes [i (count exprs)]
      (emitln (munge (params i)) " = " (temps i) ";"))
    (emitln "continue;")))
(defmethod emit* :js-var [expr] (emit-var expr))
(defn- comma-sep [xs] (interpose "," xs))
(defn emit-dot [{:keys [target field method args env]}]
  (emit-wrap
    env
    (if field
      (emits target "." (munge field #{}))
      (emits target "." (munge method #{}) "(" (comma-sep args) ")"))))
(defn sublib-select [sublib]
  (when sublib
    (let [xs (string/split sublib #"\.")]
      (apply
        str
        (map (fn* [p1__5795#] (str "['" p1__5795# "']")) xs)))))
(defn cached-core [ns ext opts]
  (and
    (= :none (:optimizations opts))
    (not= "cljc" ext)
    (= (quote cljs.core) ns)
    (io/resource "cljs/core.aot.js")))
(defn emits-symbol [sym]
  (let [ns (namespace sym)
        name (name sym)
        symstr (if-not (nil? ns) (str ns "/" name) name)]
    (emits "new cljs.core.Symbol(")
    (emit-constant ns)
    (emits ",")
    (emit-constant name)
    (emits ",")
    (emit-constant symstr)
    (emits ",")
    (emit-constant (hash sym))
    (emits ",")
    (emit-constant nil)
    (emits ")")))
(defmethod emit* :host-field [ast] (emit-dot ast))
(defmethod
  emit-constant*
  clojure.lang.Keyword
  [x]
  (if-let [value (and
                   (-> (clojure.core/deref env/*compiler*)
                    :options
                    :emit-constants)
                   (-> (clojure.core/deref env/*compiler*)
                    :cljs.analyzer/constant-table
                    x))]
    (emits "cljs.core." value)
    (emits-keyword x)))
(defmethod
  emit*
  :js
  [{:keys [op env code segs args]}]
  (if (and code (.startsWith (string/trim code) "/*"))
    (emits code)
    (emit-wrap
      env
      (if code
        (emits code)
        (emits
          (interleave
            (concat segs (repeat nil))
            (concat args [nil])))))))
(defn find-source [file] (ana/parse-ns file))
(defn cljs-files-in
  "Return a sequence of all .cljs and .cljc files in the given directory."
  [dir]
  (map
    io/file
    (reduce
      (fn [m x]
        (if (.endsWith x ".cljs")
          (cond->
            (conj m x)
            (contains? m (str (subs x 0 (dec (count x))) "c"))
            (set/difference #{(str (subs x 0 (dec (count x))) "c")}))
          (cond->
            m
            (not (contains? m (str (subs x 0 (dec (count x))) "s")))
            (conj x))))
      #{}
      (into
        []
        (comp
          (filter
            (fn*
              [p1__6048#]
              (let [name (.getName p1__6048#)]
                (and
                  (or
                    (.endsWith name ".cljs")
                    (.endsWith name ".cljc"))
                  (not= \. (first name))
                  (not (contains? cljs-reserved-file-names name))))))
          (map (fn* [p1__6049#] (.getPath p1__6049#))))
        (file-seq dir)))))
(defn all-distinct? [xs] (apply distinct? xs))
(defmethod
  emit*
  :new
  [{ctor :class  :keys [args env]}]
  (emit-wrap env (emits "(new " ctor "(" (comma-sep args) "))")))
(defmethod
  emit*
  :map
  [{:keys [env keys vals]}]
  (emit-wrap env (emit-map keys vals comma-sep distinct-keys?)))
(defn emit-with-meta [expr meta]
  (emits "cljs.core.with_meta(" expr "," meta ")"))
(defmethod
  emit-constant*
  String
  [x]
  (emits (wrap-in-double-quotes (escape-string x))))
(defmethod emit-constant* Integer [x] (emits x))
(defmethod
  emit*
  :set!
  [{:keys [target val env]}]
  (emit-wrap env (emits "(" target " = " val ")")))
(defn url-path [f] (.getPath (.toURL (.toURI f))))
(defmethod
  emit*
  :throw
  [{throw :exception  :keys [env]}]
  (if (= :expr (:context env))
    (emits "(function(){throw " throw "})()")
    (emitln "throw " throw ";")))
(defn _emitln []
  (newline)
  (when *source-map-data*
    (.set *source-map-data-gen-col* 0)
    (swap!
      *source-map-data*
      (fn [{:keys [gen-line]  :as m}]
        (assoc m :gen-line (inc gen-line)))))
  nil)
(defn emit-map [keys vals comma-sep distinct-keys?]
  (cond
    (zero? (count keys)) (emits "cljs.core.PersistentArrayMap.EMPTY")
    (<= (count keys) array-map-threshold) (if
                                            (distinct-keys? keys)
                                            (emits
                                              "new cljs.core.PersistentArrayMap(null, "
                                              (count keys)
                                              ", ["
                                              (comma-sep
                                                (interleave keys vals))
                                              "], null)")
                                            (emits
                                              "cljs.core.PersistentArrayMap.createAsIfByAssoc(["
                                              (comma-sep
                                                (interleave keys vals))
                                              "])"))
    :else (emits
            "cljs.core.PersistentHashMap.fromArrays(["
            (comma-sep keys)
            "],["
            (comma-sep vals)
            "])")))
(defmethod
  emit-constant*
  clojure.lang.Symbol
  [x]
  (if-let [value (and
                   (-> (clojure.core/deref env/*compiler*)
                    :options
                    :emit-constants)
                   (-> (clojure.core/deref env/*compiler*)
                    :cljs.analyzer/constant-table
                    x))]
    (emits "cljs.core." value)
    (emits-symbol x)))
(defmethod
  emit-constant*
  :default
  [x]
  (throw
    (ex-info
      (str
        "failed compiling constant: "
        x
        "; "
        (pr-str (type x))
        " is not a valid ClojureScript constant.")
      {:constant x 
       :type (type x) 
       :clojure.error/phase :compilation})))
(defn macro-ns? [ns ext opts]
  (or
    (= "clj" ext)
    (= (quote cljs.core$macros) ns)
    (and (= ns (quote cljs.core)) (= "cljc" ext))
    (:macros-ns opts)))
(defn emit-js-array [items comma-sep] (emits "[" (comma-sep items) "]"))
(defmethod
  emit*
  :const
  [{:keys [form env]}]
  (when-not (= :statement (:context env))
    (emit-wrap env (emit-constant form))))
(defmethod
  emit-constant*
  Double
  [x]
  (let [x (double x)]
    (cond
      (Double/isNaN x) (emits "NaN")
      (Double/isInfinite x) (emits
                              (if (pos? x) "Infinity" "-Infinity"))
      :else (emits x))))
(defn emit-list [items comma-sep]
  (if (empty? items)
    (emits "cljs.core.List.EMPTY")
    (emits "cljs.core.list(" (comma-sep items) ")")))
(defmethod emit-constant* Long [x] (emits "(" x ")"))
(defmethod
  emit*
  :with-meta
  [{:keys [expr meta env]}]
  (emit-wrap env (emit-with-meta expr meta)))
(defn emit-constant [v]
  (let [m (ana/elide-irrelevant-meta (meta v))]
    (if (some? (seq m))
      (emit-with-meta
        (fn* [] (emit-constant-no-meta v))
        (fn* [] (emit-constant-no-meta m)))
      (emit-constant-no-meta v))))
(defmethod emit* :binding [expr] (emit-var expr))
(defmethod emit* :let [ast] (emit-let ast false))
(defn emit-fn-method [{expr :body 
                       :keys [type name params env recurs]}]
  (emit-wrap
    env
    (emits "(function " (munge name) "(")
    (emit-fn-params params)
    (emitln "){")
    (when type (emitln "var self__ = this;"))
    (when recurs (emitln "while(true){"))
    (emits expr)
    (when recurs (emitln "break;") (emitln "}"))
    (emits "})")))
(defmethod
  emit-constant*
  Character
  [x]
  (emits (wrap-in-double-quotes (escape-char x))))
(defn emit-fn-params [params]
  (doseq [param params]
    (emit param)
    (when-not (= param (last params)) (emits ","))))
(defn get-first-ns-segment
  "Gets the part up to the first `.` of a namespace.\n   Returns the empty string for nil.\n   Returns the entire string if no `.` in namespace"
  [ns]
  (let [ns (str ns) idx (.indexOf ns ".")]
    (if (== -1 idx) ns (subs ns 0 idx))))
(defmethod emit-constant* nil [x] (emits "null"))
(defn munge-reserved [reserved]
  (fn [s] (if-not (nil? (get reserved s)) (str s "$") s)))
(defn emit-set [items comma-sep distinct-constants?]
  (cond
    (empty? items) (emits "cljs.core.PersistentHashSet.EMPTY")
    (distinct-constants? items) (emits
                                  "new cljs.core.PersistentHashSet(null, new cljs.core.PersistentArrayMap(null, "
                                  (count items)
                                  ", ["
                                  (comma-sep
                                    (interleave items (repeat "null")))
                                  "], null), null)")
    :else (emits
            "cljs.core.PersistentHashSet.createAsIfByAssoc(["
            (comma-sep items)
            "])")))
(clojure.core/defn emit-wrap
  ([&form &env env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote env__5288__auto__))
                (clojure.core/list env)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/when))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/=))
                    (clojure.core/list :return)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list :context)
                          (clojure.core/list
                            (quote env__5288__auto__))))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.compiler/emits))
                    (clojure.core/list "return ")))))))
        body
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/when-not))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/=))
                    (clojure.core/list :expr)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list :context)
                          (clojure.core/list
                            (quote env__5288__auto__))))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.compiler/emitln))
                    (clojure.core/list ";")))))))))))
(defn- escape-char [c]
  (let [cp (.hashCode c)]
    (case
      cp
      34
      "\\\""
      92
      "\\\\"
      8
      "\\b"
      12
      "\\f"
      10
      "\\n"
      13
      "\\r"
      9
      "\\t"
      (if (< 31 cp 127) c (format "\\u%04X" cp)))))
(defn fn-self-name [{:keys [name info]  :as name-var}]
  (let [name (string/replace (str name) ".." "_DOT__DOT_")
        {:keys [ns fn-scope]} info
        scoped-name (apply
                      str
                      (interpose
                        "_$_"
                        (concat
                          (map (comp str :name) fn-scope)
                          [name])))]
    (symbol
      (munge (str (string/replace (str ns) "." "$") "$" scoped-name)))))
(defmethod
  emit*
  :js-object
  [{:keys [keys vals env]}]
  (emit-wrap env (emit-js-object (map vector keys vals) identity)))
(defn emit-constants-comma-sep [cs]
  (fn []
    (doall
      (map-indexed
        (fn [i m] (if (even? i) (emit-constant m) (emits m)))
        (comma-sep cs)))))
(defn emit-vector [items comma-sep]
  (if (empty? items)
    (emits "cljs.core.PersistentVector.EMPTY")
    (let [cnt (count items)]
      (if (< cnt 32)
        (emits
          "new cljs.core.PersistentVector(null, "
          cnt
          ", 5, cljs.core.PersistentVector.EMPTY_NODE, ["
          (comma-sep items)
          "], null)")
        (emits
          "cljs.core.PersistentVector.fromArray(["
          (comma-sep items)
          "], true)")))))
(defn hash-scope [s] (hash-combine (hash (:name s)) (shadow-depth s)))
(defn distinct-keys? [keys]
  (let [keys (map ana/unwrap-quote keys)]
    (and
      (every? (fn* [p1__5343#] (= (:op p1__5343#) :const)) keys)
      (= (count (into #{} keys)) (count keys)))))
(defn emit-arguments-to-array
  "Emit code that copies function arguments into an array starting at an index.\n  Returns name of var holding the array."
  [startslice]
  (assert (and (>= startslice 0) (integer? startslice)))
  (let [mname (munge (gensym)) i (str mname "__i") a (str mname "__a")]
    (emitln
      "var "
      i
      " = 0, "
      a
      " = new Array(arguments.length -  "
      startslice
      ");")
    (emitln
      "while ("
      i
      " < "
      a
      ".length) {"
      a
      "["
      i
      "] = arguments["
      i
      " + "
      startslice
      "]; ++"
      i
      ";}")
    a))
(defn checking-types? []
  (#{:warning :error}
    (get-in
      (clojure.core/deref env/*compiler*)
      [:options :closure-warnings :check-types])))
(defn find-root-sources [src-dir]
  (let [src-dir-file (io/file src-dir)]
    (map find-source (cljs-files-in src-dir-file))))
(defn munge
  ([s] (munge s js-reserved))
  ([s reserved]
    (if (map? s)
      (let [name-var s
            name (:name name-var)
            field (:field name-var)
            info (:info name-var)]
        (if-not (nil? (:fn-self-name info))
          (fn-self-name s)
          (let [depth (shadow-depth s)
                code (hash-scope s)
                renamed (get *lexical-renames* code)
                name (cond
                       (true? field) (str "self__." name)
                       (not (nil? renamed)) renamed
                       :else name)
                munged-name (munge name reserved)]
            (if (or (true? field) (zero? depth))
              munged-name
              (symbol (str munged-name "__$" depth))))))
      (let [ss (string/replace (str s) ".." "_DOT__DOT_")
            ss (string/replace ss #"\/(.)" ".$1")
            rf (munge-reserved reserved)
            ss (map rf (string/split ss #"\."))
            ss (string/join "." ss)
            ms (clojure.lang.Compiler/munge ss)]
        (if (symbol? s) (symbol ms) ms)))))
(defmethod
  emit*
  :vector
  [{:keys [items env]}]
  (emit-wrap env (emit-vector items comma-sep)))
(defmethod emit* :local [expr] (emit-var expr))
(defmethod emit* :loop [ast] (emit-let ast true))
(defn emits
  ([])
  ([a]
    (cond
      (nil? a) nil
      (map? a) (emit a)
      (seq? a) (apply emits a)
      (fn? a) (a)
      :else (let [s (cond-> a (not (string? a)) .toString)]
              (when-some
                [gen-col *source-map-data-gen-col*]
                (.addAndGet gen-col (.length s)))
              (.write *out* s)))
    nil)
  ([a b] (emits a) (emits b))
  ([a b c] (emits a) (emits b) (emits c))
  ([a b c d] (emits a) (emits b) (emits c) (emits d))
  ([a b c d e] (emits a) (emits b) (emits c) (emits d) (emits e))
  ([a b c d e & xs]
    (emits a)
    (emits b)
    (emits c)
    (emits d)
    (emits e)
    (doseq [x xs] (emits x))))
(defn emit-let [{expr :body  :keys [bindings env]} is-loop]
  (let [context (:context env)]
    (when (= :expr context) (emits "(function (){"))
    (binding [*lexical-renames* (into
                                  *lexical-renames*
                                  (when
                                    (= :statement context)
                                    (map
                                      (fn 
                                        [binding]
                                        (let 
                                          [name (:name binding)]
                                          (vector
                                            (hash-scope binding)
                                            (gensym (str name "-")))))
                                      bindings)))]
      (doseq [{:keys [init]  :as binding} bindings]
        (emits "var ")
        (emit binding)
        (emitln " = " init ";"))
      (when is-loop (emitln "while(true){"))
      (emits expr)
      (when is-loop (emitln "break;") (emitln "}")))
    (when (= :expr context) (emits "})()"))))
(defn emit-externs
  ([externs]
    (emit-externs
      []
      externs
      (atom #{})
      (when env/*compiler* (ana/get-externs))))
  ([prefix externs top-level known-externs]
    (loop [ks (seq (keys externs))]
      (when ks
        (let [k (first ks) [top :as prefix'] (conj prefix k)]
          (when (and
                  (not= (quote prototype) k)
                  (nil? (get-in known-externs prefix')))
            (if-not (or
                      (contains? (clojure.core/deref top-level) top)
                      (contains? known-externs top))
              (do
                (emitln
                  "var "
                  (string/join "." (map munge prefix'))
                  ";")
                (swap! top-level conj top))
              (emitln (string/join "." (map munge prefix')) ";")))
          (let [m (get externs k)]
            (when-not (empty? m)
              (emit-externs prefix' m top-level known-externs))))
        (recur (next ks))))))
(defn emitln
  ([] (_emitln))
  ([a] (emits a) (_emitln))
  ([a b] (emits a) (emits b) (_emitln))
  ([a b c] (emits a) (emits b) (emits c) (_emitln))
  ([a b c d] (emits a) (emits b) (emits c) (emits d) (_emitln))
  ([a b c d e]
    (emits a)
    (emits b)
    (emits c)
    (emits d)
    (emits e)
    (_emitln))
  ([a b c d e & xs]
    (emits a)
    (emits b)
    (emits c)
    (emits d)
    (emits e)
    (doseq [x xs] (emits x))
    (_emitln)))
(defmethod
  emit*
  :fn
  [{variadic :variadic? 
    :keys
    [name env methods max-fixed-arity recur-frames in-loop loop-lets]}]
  (when-not (= :statement (:context env))
    (let [recur-params (mapcat
                         :params
                         (filter
                           (fn*
                             [p1__5608#]
                             (and
                               p1__5608#
                               (clojure.core/deref (:flag p1__5608#))))
                           recur-frames))
          loop-locals (->>
                        (concat
                          recur-params
                          (when (or in-loop (seq recur-params))
                            (mapcat :params loop-lets)))
                        (map munge)
                        seq)]
      (when loop-locals
        (when (= :return (:context env)) (emits "return "))
        (emitln
          "((function ("
          (comma-sep (map munge loop-locals))
          "){")
        (when-not (= :return (:context env)) (emits "return ")))
      (if (= 1 (count methods))
        (if variadic
          (emit-variadic-fn-method (assoc (first methods) :name name))
          (emit-fn-method (assoc (first methods) :name name)))
        (let [name (or name (gensym))
              mname (munge name)
              maxparams (apply max-key count (map :params methods))
              mmap (into
                     {}
                     (map
                       (fn [method] [(munge
                                       (symbol
                                         (str
                                           mname
                                           "__"
                                           (count (:params method)))))
                                     method])
                       methods))
              ms (sort-by
                   (fn*
                     [p1__5609#]
                     (-> p1__5609# second :params count))
                   (seq mmap))]
          (when (= :return (:context env)) (emits "return "))
          (emitln "(function() {")
          (emitln "var " mname " = null;")
          (doseq [[n meth] ms]
            (emits "var " n " = ")
            (if (:variadic? meth)
              (emit-variadic-fn-method meth)
              (emit-fn-method meth))
            (emitln ";"))
          (emitln
            mname
            " = function("
            (comma-sep
              (if variadic
                (concat (butlast maxparams) [(quote var_args)])
                maxparams))
            "){")
          (when variadic
            (emits "var ")
            (emit (last maxparams))
            (emitln " = var_args;"))
          (emitln "switch(arguments.length){")
          (doseq [[n meth] ms]
            (if (:variadic? meth)
              (do
                (emitln "default:")
                (let [restarg (munge (gensym))]
                  (emitln "var " restarg " = null;")
                  (emitln
                    "if (arguments.length > "
                    max-fixed-arity
                    ") {")
                  (let [a (emit-arguments-to-array max-fixed-arity)]
                    (emitln
                      restarg
                      " = new cljs.core.IndexedSeq("
                      a
                      ",0,null);"))
                  (emitln "}")
                  (emitln
                    "return "
                    n
                    ".cljs$core$IFn$_invoke$arity$variadic("
                    (comma-sep (butlast maxparams))
                    (when (> (count maxparams) 1) ", ")
                    restarg
                    ");")))
              (let [pcnt (count (:params meth))]
                (emitln "case " pcnt ":")
                (emitln
                  "return "
                  n
                  ".call(this"
                  (if (zero? pcnt)
                    nil
                    (list "," (comma-sep (take pcnt maxparams))))
                  ");"))))
          (emitln "}")
          (let [arg-count-js (if (=
                                   (quote self__)
                                   (->
                                    ms
                                    first
                                    val
                                    :params
                                    first
                                    :name))
                               "(arguments.length - 1)"
                               "arguments.length")]
            (emitln
              "throw(new Error('Invalid arity: ' + "
              arg-count-js
              "));"))
          (emitln "};")
          (when variadic
            (emitln
              mname
              ".cljs$lang$maxFixedArity = "
              max-fixed-arity
              ";")
            (emitln
              mname
              ".cljs$lang$applyTo = "
              (some
                (fn*
                  [p1__5610#]
                  (let [[n m] p1__5610#] (when (:variadic? m) n)))
                ms)
              ".cljs$lang$applyTo;"))
          (doseq [[n meth] ms]
            (let [c (count (:params meth))]
              (if (:variadic? meth)
                (emitln
                  mname
                  ".cljs$core$IFn$_invoke$arity$variadic = "
                  n
                  ".cljs$core$IFn$_invoke$arity$variadic;")
                (emitln
                  mname
                  ".cljs$core$IFn$_invoke$arity$"
                  c
                  " = "
                  n
                  ";"))))
          (emitln "return " mname ";")
          (emitln "})()")))
      (when loop-locals (emitln ";})(" (comma-sep loop-locals) "))")))))
(defmethod
  emit*
  :do
  [{:keys [statements ret env]}]
  (let [context (:context env)]
    (when (and (seq statements) (= :expr context))
      (emitln "(function (){"))
    (doseq [s statements] (emitln s))
    (emit ret)
    (when (and (seq statements) (= :expr context)) (emitln "})()"))))
(defn emit [ast]
  (when *source-map-data*
    (let [{:keys [env]} ast]
      (when (:line env)
        (let [{:keys [line column]} env]
          (swap!
            *source-map-data*
            (fn [m]
              (let [minfo (cond->
                            {:gcol (.get *source-map-data-gen-col*) 
                             :gline (:gen-line m)}
                            (#{:binding :var :js-var :local} (:op ast))
                            (assoc :name (str (-> ast :info :name))))]
                (update-in
                  m
                  [:source-map (dec line)]
                  (fnil
                    (fn [line]
                      (update-in
                        line
                        [(if column (dec column) 0)]
                        (fnil (fn [column] (conj column minfo)) [])))
                    (sorted-map))))))))))
  (emit* ast))
(defn emit-var [{:keys [info env form]  :as ast}]
  (if-let [const-expr (:const-expr ast)]
    (emit (assoc const-expr :env env))
    (let [{:keys [options]  :as cenv} (clojure.core/deref
                                        env/*compiler*)
          var-name (:name info)
          info (if (= (namespace var-name) "js")
                 (let [js-module-name (get-in
                                        cenv
                                        [:js-module-index
                                         (name var-name)
                                         :name])]
                   (or js-module-name (name var-name)))
                 info)]
      (if (:binding-form? ast)
        (emits (munge ast))
        (when-not (= :statement (:context env))
          (let [reserved (cond->
                           js-reserved
                           (and
                             (es5>= (:language-out options))
                             (some? (namespace var-name)))
                           (set/difference ana/es5-allowed))
                js-module (get-in
                            cenv
                            [:js-namespaces
                             (or
                               (namespace var-name)
                               (name var-name))])
                info (cond->
                       info
                       (not= form (quote js/-Infinity))
                       (munge reserved))]
            (emit-wrap
              env
              (case
                (:module-type js-module)
                :commonjs
                (if (namespace var-name)
                  (emits
                    (munge (namespace var-name) reserved)
                    "[\"default\"]."
                    (munge (name var-name) reserved))
                  (emits
                    (munge (name var-name) reserved)
                    "[\"default\"]"))
                :es6
                (if (and
                      (namespace var-name)
                      (= "default" (name var-name)))
                  (emits
                    (munge (namespace var-name) reserved)
                    "[\"default\"]")
                  (emits info))
                (emits info)))))))))
(defmethod
  emit*
  :if
  [{:keys [test then else env unchecked]}]
  (let [context (:context env)
        checked (not (or unchecked (safe-test? env test)))]
    (cond
      (truthy-constant? test) (emitln then)
      (falsey-constant? test) (emitln else)
      :else (if (= :expr context)
              (emits
                "("
                (when checked "cljs.core.truth_")
                "("
                test
                ")?"
                then
                ":"
                else
                ")")
              (do
                (if checked
                  (emitln "if(cljs.core.truth_(" test ")){")
                  (emitln "if(" test "){"))
                (emitln then "} else {")
                (emitln else "}"))))))
(defmethod
  emit*
  :ns*
  [{:keys [name requires uses require-macros reloads env deps]}]
  (load-libs requires nil (:require reloads) deps name)
  (load-libs uses requires (:use reloads) deps name)
  (when (:repl-env env) (emitln "'nil';")))
(defmethod
  emit*
  :invoke
  [{f :fn  :keys [args env]  :as expr}]
  (let [info (:info f)
        fn? (and
              ana/*cljs-static-fns*
              (not (:dynamic info))
              (:fn-var info))
        protocol (:protocol info)
        tag (ana/infer-tag env (first (:args expr)))
        proto? (and
                 protocol
                 tag
                 (or
                   (and
                     ana/*cljs-static-fns*
                     protocol
                     (= tag (quote not-native)))
                   (and
                     (or ana/*cljs-static-fns* (:protocol-inline env))
                     (or
                       (= protocol tag)
                       (and
                         (not (set? tag))
                         (not
                           ((quote
                              #{clj
                                boolean
                                object
                                any
                                js
                                number
                                clj-or-nil
                                array
                                string
                                function
                                clj-nil})
                             tag))
                         (when-let [ps
                                    (:protocols
                                      (ana/resolve-existing-var
                                        env
                                        (vary-meta
                                          tag
                                          assoc
                                          :cljs.analyzer/no-resolve
                                          true)))]
                           (ps protocol)))))))
        first-arg-tag (ana/infer-tag env (first (:args expr)))
        opt-not? (and
                   (= (:name info) (quote cljs.core/not))
                   (= first-arg-tag (quote boolean)))
        opt-count? (and
                     (= (:name info) (quote cljs.core/count))
                     (boolean ((quote #{array string}) first-arg-tag)))
        ns (:ns info)
        ftag (ana/infer-tag env f)
        js? (or (= ns (quote js)) (= ns (quote Math)) (:foreign info))
        goog? (when ns
                (or
                  (= ns (quote goog))
                  (when-let [ns-str (str ns)]
                    (= (get (string/split ns-str #"\.") 0 nil) "goog"))
                  (not
                    (contains?
                      (:cljs.analyzer/namespaces
                        (clojure.core/deref env/*compiler*))
                      ns))))
        keyword? (or
                   (= (quote cljs.core/Keyword) ftag)
                   (let [f (ana/unwrap-quote f)]
                     (and
                       (= (-> f :op) :const)
                       (keyword? (-> f :form)))))
        [f variadic-invoke] (if fn?
                              (let [arity (count args)
                                    variadic? (:variadic? info)
                                    mps (:method-params info)
                                    mfa (:max-fixed-arity info)]
                                (cond
                                  (and
                                    (not variadic?)
                                    (= (count mps) 1))
                                  [f nil]
                                  (and variadic? (> arity mfa))
                                  [(update-in
                                     f
                                     [:info]
                                     (fn 
                                       [info]
                                       (->
                                        info
                                        (assoc
                                          :name
                                          (symbol
                                            (str
                                              (munge info)
                                              ".cljs$core$IFn$_invoke$arity$variadic")))
                                        (update-in
                                          [:info]
                                          (fn*
                                            [p1__5734#]
                                            (->
                                             p1__5734#
                                             (dissoc :shadow)
                                             (dissoc
                                               :fn-self-name)))))))
                                   {:max-fixed-arity mfa}]
                                  :else
                                  (let 
                                    [arities (map count mps)]
                                    (if
                                      (some #{arity} arities)
                                      [(update-in
                                         f
                                         [:info]
                                         (fn 
                                           [info]
                                           (->
                                            info
                                            (assoc
                                              :name
                                              (symbol
                                                (str
                                                  (munge info)
                                                  ".cljs$core$IFn$_invoke$arity$"
                                                  arity)))
                                            (update-in
                                              [:info]
                                              (fn*
                                                [p1__5735#]
                                                (->
                                                 p1__5735#
                                                 (dissoc :shadow)
                                                 (dissoc
                                                   :fn-self-name)))))))
                                       nil]
                                      [f nil]))))
                              [f nil])]
    (emit-wrap
      env
      (cond
        opt-not? (emits "(!(" (first args) "))")
        opt-count? (emits "((" (first args) ").length)")
        proto? (let [pimpl (str
                             (munge (protocol-prefix protocol))
                             (munge (name (:name info)))
                             "$arity$"
                             (count args))]
                 (emits
                   (first args)
                   "."
                   pimpl
                   "("
                   (comma-sep (cons "null" (rest args)))
                   ")"))
        keyword? (emits
                   f
                   ".cljs$core$IFn$_invoke$arity$"
                   (count args)
                   "("
                   (comma-sep args)
                   ")")
        variadic-invoke (let [mfa (:max-fixed-arity variadic-invoke)]
                          (emits
                            f
                            "("
                            (comma-sep (take mfa args))
                            (when-not (zero? mfa) ",")
                            "cljs.core.prim_seq.cljs$core$IFn$_invoke$arity$2(["
                            (comma-sep (drop mfa args))
                            "], 0))"))
        (or fn? js? goog?) (emits f "(" (comma-sep args) ")")
        :else (if (and
                    ana/*cljs-static-fns*
                    (#{:var :js-var :local} (:op f)))
                (let [fprop (str
                              ".cljs$core$IFn$_invoke$arity$"
                              (count args))]
                  (if ana/*fn-invoke-direct*
                    (emits
                      "("
                      f
                      fprop
                      " ? "
                      f
                      fprop
                      "("
                      (comma-sep args)
                      ") : "
                      f
                      "("
                      (comma-sep args)
                      "))")
                    (emits
                      "("
                      f
                      fprop
                      " ? "
                      f
                      fprop
                      "("
                      (comma-sep args)
                      ") : "
                      f
                      ".call("
                      (comma-sep (cons "null" args))
                      "))")))
                (emits
                  f
                  ".call("
                  (comma-sep (cons "null" args))
                  ")"))))))
(defn emit-apply-to [{:keys [name params env]}]
  (let [arglist (gensym "arglist__")
        delegate-name (str (munge name) "__delegate")]
    (emitln "(function (" arglist "){")
    (doseq [[i param] (map-indexed vector (drop-last 2 params))]
      (emits "var ")
      (emit param)
      (emits " = cljs.core.first(")
      (emitln arglist ");")
      (emitln arglist " = cljs.core.next(" arglist ");"))
    (if (< 1 (count params))
      (do
        (emits "var ")
        (emit (last (butlast params)))
        (emitln " = cljs.core.first(" arglist ");")
        (emits "var ")
        (emit (last params))
        (emitln " = cljs.core.rest(" arglist ");")
        (emits "return " delegate-name "(")
        (doseq [param params]
          (emit param)
          (when-not (= param (last params)) (emits ",")))
        (emitln ");"))
      (do
        (emits "var ")
        (emit (last params))
        (emitln " = cljs.core.seq(" arglist ");")
        (emits "return " delegate-name "(")
        (doseq [param params]
          (emit param)
          (when-not (= param (last params)) (emits ",")))
        (emitln ");")))
    (emits "})")))
(defmethod
  emit*
  :try
  [{try :body  :keys [env catch name finally]}]
  (let [context (:context env)]
    (if (or name finally)
      (do
        (when (= :expr context) (emits "(function (){"))
        (emits "try{" try "}")
        (when name (emits "catch (" (munge name) "){" catch "}"))
        (when finally
          (assert
            (not= :const (:op (ana/unwrap-quote finally)))
            "finally block cannot contain constant")
          (emits "finally {" finally "}"))
        (when (= :expr context) (emits "})()")))
      (emits try))))
(defmethod
  emit-constant*
  java.util.regex.Pattern
  [x]
  (if (= "" (str x))
    (emits "(new RegExp(\"\"))")
    (let [[_ flags pattern] (re-find
                              #"^(?:\(\?([idmsux]*)\))?(.*)"
                              (str x))]
      (emits
        \/
        (.replaceAll (re-matcher #"/" pattern) "\\\\/")
        \/
        flags))))
(defn emit-comment
  "Emit a nicely formatted comment string."
  ([doc jsdoc] (emit-comment nil doc jsdoc))
  ([env doc jsdoc]
    (let [docs (when doc [doc])
          docs (if jsdoc (concat docs jsdoc) docs)
          docs (remove nil? docs)]
      (letfn
        [(print-comment-lines
           [e]
           (let [[x & ys] (map
                            (fn*
                              [p1__5509#]
                              (if (checking-types?)
                                (munge-param-return env p1__5509#)
                                p1__5509#))
                            (string/split-lines e))]
             (emitln " * " (string/replace x "*/" "* /"))
             (doseq [next-line ys]
               (emitln
                 " * "
                 (-> next-line
                  (string/replace #"^   " "")
                  (string/replace "*/" "* /"))))))]
        (when (seq docs)
          (emitln "/**")
          (doseq [e docs] (when e (print-comment-lines e)))
          (emitln " */"))))))
(defmethod
  emit*
  :defrecord
  [{:keys [t fields pmasks body protocols]}]
  (let [fields (concat
                 (map munge fields)
                 (quote [__meta __extmap __hash]))]
    (emitln "")
    (emitln "/**")
    (emitln "* @constructor")
    (doseq [protocol protocols]
      (emitln " * @implements {" (munge (str protocol)) "}"))
    (emitln "*/")
    (emitln (munge t) " = (function (" (comma-sep fields) "){")
    (doseq [fld fields] (emitln "this." fld " = " fld ";"))
    (doseq [[pno pmask] pmasks]
      (emitln
        "this.cljs$lang$protocol_mask$partition"
        pno
        "$ = "
        pmask
        ";"))
    (emitln "});")
    (emit body)))
(defmethod
  emit*
  :deftype
  [{:keys [t fields pmasks body protocols]}]
  (let [fields (map munge fields)]
    (emitln "")
    (emitln "/**")
    (emitln "* @constructor")
    (doseq [protocol protocols]
      (emitln " * @implements {" (munge (str protocol)) "}"))
    (emitln "*/")
    (emitln (munge t) " = (function (" (comma-sep fields) "){")
    (doseq [fld fields] (emitln "this." fld " = " fld ";"))
    (doseq [[pno pmask] pmasks]
      (emitln
        "this.cljs$lang$protocol_mask$partition"
        pno
        "$ = "
        pmask
        ";"))
    (emitln "});")
    (emit body)))
(defn- escape-string [s]
  (let [sb (StringBuilder. (count s))]
    (doseq [c s] (.append sb (escape-char c)))
    (.toString sb)))
(defn emit-js-object [items emit-js-object-val]
  (emits "({")
  (when-let [items (seq items)]
    (let [[[k v] & r] items]
      (emits "\"" (name k) "\": " (emit-js-object-val v))
      (doseq [[k v] r]
        (emits ", \"" (name k) "\": " (emit-js-object-val v)))))
  (emits "})"))
(defn emit-variadic-fn-method [{expr :body 
                                max-fixed-arity :fixed-arity 
                                variadic :variadic? 
                                :keys [type name params env recurs] 
                                :as f}]
  (emit-wrap
    env
    (let [name (or name (gensym))
          mname (munge name)
          delegate-name (str mname "__delegate")]
      (emitln "(function() { ")
      (emits "var " delegate-name " = function (")
      (doseq [param params]
        (emit param)
        (when-not (= param (last params)) (emits ",")))
      (emitln "){")
      (when type (emitln "var self__ = this;"))
      (when recurs (emitln "while(true){"))
      (emits expr)
      (when recurs (emitln "break;") (emitln "}"))
      (emitln "};")
      (emitln
        "var "
        mname
        " = function ("
        (comma-sep
          (if variadic
            (concat (butlast params) [(quote var_args)])
            params))
        "){")
      (when type (emitln "var self__ = this;"))
      (when variadic
        (emits "var ")
        (emit (last params))
        (emitln " = null;")
        (emitln "if (arguments.length > " (dec (count params)) ") {")
        (let [a (emit-arguments-to-array (dec (count params)))]
          (emitln
            "  "
            (last params)
            " = new cljs.core.IndexedSeq("
            a
            ",0,null);"))
        (emitln "} "))
      (emits "return " delegate-name ".call(this,")
      (doseq [param params]
        (emit param)
        (when-not (= param (last params)) (emits ",")))
      (emits ");")
      (emitln "};")
      (emitln mname ".cljs$lang$maxFixedArity = " max-fixed-arity ";")
      (emits mname ".cljs$lang$applyTo = ")
      (emit-apply-to (assoc f :name name))
      (emitln ";")
      (emitln
        mname
        ".cljs$core$IFn$_invoke$arity$variadic = "
        delegate-name
        ";")
      (emitln "return " mname ";")
      (emitln "})()"))))
(defn shadow-depth [s]
  (let [{:keys [name info]} s]
    (loop [d 0 {:keys [shadow]} info]
      (cond
        shadow (recur (inc d) shadow)
        (find-ns-starts-with (str name)) (inc d)
        :else d))))
(defn emit-source [src dest ext opts]
  (with-open [out (io/make-writer dest {})]
    (binding [*out* out
              ana/*cljs-ns* (quote cljs.user)
              ana/*cljs-file* (.getPath src)
              reader/*alias-map* (or
                                   (ana/get-bridged-alias-map)
                                   reader/*alias-map*
                                   {})
              ana/*checked-arrays* (or
                                     ana/*checked-arrays*
                                     (:checked-arrays opts))
              ana/*cljs-static-fns* (or
                                      ana/*cljs-static-fns*
                                      (:static-fns opts))
              *source-map-data* (when
                                  (:source-map opts)
                                  (atom
                                    {:source-map (sorted-map) 
                                     :gen-line 0}))
              *source-map-data-gen-col* (AtomicLong.)
              find-ns-starts-with (memoize find-ns-starts-with)]
      (emitln (compiled-by-string opts))
      (with-open [rdr (io/reader src)]
        (let [env (ana/empty-env)
              emitter (when (:parallel-build opts)
                        (Executors/newSingleThreadExecutor))
              emit (if emitter
                     (fn*
                       [p1__5982#]
                       (.execute
                         emitter
                         (bound-fn [] (emit p1__5982#))))
                     emit)]
          (loop [forms (ana/forms-seq* rdr (util/path src))
                 ns-name nil
                 deps []]
            (if (seq forms)
              (let [env (assoc
                          env
                          :ns
                          (ana/get-namespace ana/*cljs-ns*))
                    {:keys [op]  :as ast} (ana/analyze
                                            env
                                            (first forms)
                                            nil
                                            opts)]
                (cond
                  (= op :ns) (let [ns-name (:name ast)
                                   ns-name
                                   (if
                                     (and
                                       (= (quote cljs.core) ns-name)
                                       (= "cljc" ext))
                                     (quote cljs.core$macros)
                                     ns-name)]
                               (emit ast)
                               (recur
                                 (rest forms)
                                 ns-name
                                 (into deps (:deps ast))))
                  (= :ns* (:op ast)) (let 
                                       [ns-emitted? (some? ns-name)
                                        ns-name
                                        (if-not
                                          ns-emitted?
                                          (ana/gen-user-ns src)
                                          ns-name)]
                                       (if-not
                                         ns-emitted?
                                         (emit
                                           (assoc
                                             ast
                                             :name
                                             ns-name
                                             :op
                                             :ns))
                                         (emit ast))
                                       (recur
                                         (rest forms)
                                         ns-name
                                         (into deps (:deps ast))))
                  :else (let [ns-emitted? (some? ns-name)
                              ns-name (if-not
                                        ns-emitted?
                                        (ana/gen-user-ns src)
                                        ns-name)]
                          (when-not ns-emitted?
                            (emit {:op :ns  :name ns-name}))
                          (emit ast)
                          (recur (rest forms) ns-name deps))))
              (let [_ (when emitter
                        (.shutdown emitter)
                        (.awaitTermination
                          emitter
                          1000
                          TimeUnit/HOURS))
                    sm-data (when *source-map-data*
                              (assoc
                                (clojure.core/deref *source-map-data*)
                                :gen-col
                                (.get *source-map-data-gen-col*)))
                    ret (merge
                          {:ns (or ns-name (quote cljs.user)) 
                           :macros-ns (:macros-ns opts) 
                           :provides [ns-name] 
                           :requires
                           (if (= ns-name (quote cljs.core))
                             (vec (distinct deps))
                             (cond->
                               (conj
                                 (vec (distinct deps))
                                 (quote cljs.core))
                               (get-in
                                 (clojure.core/deref env/*compiler*)
                                 [:options :emit-constants])
                               (conj ana/constants-ns-sym))) 
                           :file dest 
                           :out-file (.toString dest) 
                           :source-file src}
                          (when sm-data
                            {:source-map (:source-map sm-data)}))]
                (when (and sm-data (= :none (:optimizations opts)))
                  (emit-source-map
                    src
                    dest
                    sm-data
                    (merge opts {:ext ext  :provides [ns-name]})))
                (let [path (.getPath (.toURL dest))]
                  (swap!
                    env/*compiler*
                    assoc-in
                    [:cljs.compiler/compiled-cljs path]
                    ret))
                (ana/ensure-defs ns-name)
                (let [{:keys [output-dir cache-analysis]} opts]
                  (when (and (true? cache-analysis) output-dir)
                    (ana/write-analysis-cache
                      ns-name
                      (ana/cache-file
                        src
                        (ana/parse-ns src)
                        output-dir
                        :write)
                      src))
                  ret)))))))))
(defn requires-compilation?
  "Return true if the src file requires compilation."
  ([src dest]
    (requires-compilation?
      src
      dest
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src dest opts]
    (let [{:keys [ns requires]} (ana/parse-ns src)]
      (if (and
            (= (quote cljs.loader) ns)
            (not (contains? opts :cache-key)))
        false
        (ensure
          (or
            (not (.exists dest))
            (util/changed? src dest)
            (let [version' (util/compiled-by-version dest)
                  version (util/clojurescript-version)]
              (and version (not= version version')))
            (and
              opts
              (not
                (and
                  (io/resource "cljs/core.aot.js")
                  (= (quote cljs.core) ns)))
              (not=
                (ana/build-affecting-options opts)
                (ana/build-affecting-options
                  (util/build-options dest))))
            (and
              opts
              (:source-map opts)
              (if (= (:optimizations opts) :none)
                (not (.exists (io/file (str (.getPath dest) ".map"))))
                (not
                  (get-in
                    (clojure.core/deref env/*compiler*)
                    [:cljs.compiler/compiled-cljs
                     (.getAbsolutePath dest)]))))
            (when-let [recompiled' (and
                                     *recompiled*
                                     (clojure.core/deref
                                       *recompiled*))]
              (some requires recompiled'))))))))
(defn find-ns-starts-with [needle]
  (reduce-kv
    (fn [xs ns _]
      (when (= needle (get-first-ns-segment ns)) (reduced needle)))
    nil
    (:cljs.analyzer/namespaces (clojure.core/deref env/*compiler*))))
(defmethod
  emit*
  :letfn
  [{expr :body  :keys [bindings env]}]
  (let [context (:context env)]
    (when (= :expr context) (emits "(function (){"))
    (doseq [{:keys [init]  :as binding} bindings]
      (emitln "var " (munge binding) " = " init ";"))
    (emits expr)
    (when (= :expr context) (emits "})()"))))
(defn load-libs [libs seen reloads deps ns-name]
  (let [{:keys [options js-dependency-index]} (clojure.core/deref
                                                env/*compiler*)
        {:keys [target nodejs-rt optimizations]} options
        loaded-libs (munge (quote cljs.core.*loaded-libs*))
        loaded-libs-temp (munge
                           (gensym (quote cljs.core.*loaded-libs*)))
        [node-libs libs-to-load] (let 
                                   [libs
                                    (remove
                                      (set (vals seen))
                                      (filter (set (vals libs)) deps))]
                                   (if
                                     (= :nodejs target)
                                     (let 
                                       [{node-libs true 
                                         libs-to-load false}
                                        (group-by
                                          ana/node-module-dep?
                                          libs)]
                                       [node-libs libs-to-load])
                                     [nil libs]))
        [goog-modules libs-to-load] (let 
                                      [{goog-modules true 
                                        libs-to-load false}
                                       (group-by
                                         ana/goog-module-dep?
                                         libs-to-load)]
                                      [goog-modules libs-to-load])
        global-exports-libs (filter
                              ana/dep-has-global-exports?
                              libs-to-load)]
    (when (-> libs meta :reload-all)
      (emitln
        "if(!COMPILED) "
        loaded-libs-temp
        " = "
        loaded-libs
        " || cljs.core.set([\"cljs.core\"]);")
      (emitln
        "if(!COMPILED) "
        loaded-libs
        " = cljs.core.set([\"cljs.core\"]);"))
    (doseq [lib libs-to-load]
      (cond
        (ana/foreign-dep? lib) (when
                                 (and
                                   (= :none optimizations)
                                   (not (contains? options :modules)))
                                 (let 
                                   [[lib _] (ana/lib&sublib lib)]
                                   (if
                                     nodejs-rt
                                     (let 
                                       [ijs
                                        (get
                                          js-dependency-index
                                          (name lib))]
                                       (emitln
                                         "cljs.core.load_file("
                                         (->
                                          (io/file
                                            (util/output-directory
                                              options)
                                            (or
                                              (deps/-relative-path ijs)
                                              (util/relative-name
                                                (:url ijs))))
                                          str
                                          escape-string
                                          wrap-in-double-quotes)
                                         ");"))
                                     (emitln
                                       "goog.require('"
                                       (munge lib)
                                       "');"))))
        (or (-> libs meta :reload) (= (get reloads lib) :reload)) (emitln
                                                                    "goog.require('"
                                                                    (munge
                                                                      lib)
                                                                    "', 'reload');")
        (or
          (-> libs meta :reload-all)
          (= (get reloads lib) :reload-all)) (emitln
                                               "goog.require('"
                                               (munge lib)
                                               "', 'reload-all');")
        :else (when-not (= lib (quote goog))
                (emitln "goog.require('" (munge lib) "');"))))
    (doseq [lib node-libs]
      (let [[lib' sublib] (ana/lib&sublib lib)]
        (emitln
          (munge ns-name)
          "."
          (ana/munge-node-lib lib)
          " = require('"
          lib'
          "')"
          (sublib-select sublib)
          ";")))
    (doseq [lib goog-modules]
      (let [[lib' sublib] (ana/lib&sublib lib)]
        (emitln "goog.require('" lib' "');")
        (emitln "goog.scope(function(){")
        (emitln
          (munge ns-name)
          "."
          (ana/munge-goog-module-lib lib)
          " = goog.module.get('"
          lib'
          "')"
          (sublib-select sublib)
          ";")
        (emitln "});")))
    (doseq [lib global-exports-libs]
      (let [{:keys [global-exports]} (get
                                       js-dependency-index
                                       (name
                                         (->
                                          lib
                                          ana/lib&sublib
                                          first)))]
        (emit-global-export ns-name global-exports lib)))
    (when (-> libs meta :reload-all)
      (emitln
        "if(!COMPILED) "
        loaded-libs
        " = cljs.core.into("
        loaded-libs-temp
        ", "
        loaded-libs
        ");"))))
(defmethod
  emit*
  :def
  [{:keys
    [name var init env doc goog-define jsdoc export test var-ast]}]
  (when (or init (:def-emits-var env))
    (let [mname (munge name)]
      (emit-comment
        env
        doc
        (concat
          (when goog-define [(str "@define {" goog-define "}")])
          jsdoc
          (:jsdoc init)))
      (when (= :return (:context env)) (emitln "return ("))
      (when (:def-emits-var env) (emitln "(function (){"))
      (emits var)
      (when init
        (emits
          " = "
          (if-let [define (get-define mname jsdoc)] define init)))
      (when (:def-emits-var env)
        (emitln "; return (")
        (emits
          (merge
            {:op :the-var  :env (assoc env :context :expr)}
            var-ast))
        (emitln ");})()"))
      (when (= :return (:context env)) (emitln ")"))
      (when-not (= :expr (:context env)) (emitln ";"))
      (when export
        (emitln "goog.exportSymbol('" (munge export) "', " mname ");"))
      (when (and ana/*load-tests* test)
        (when (= :expr (:context env)) (emitln ";"))
        (emitln var ".cljs$lang$test = " test ";")))))
(defn emit-constants-table [table]
  (emitln "goog.provide('" (munge ana/constants-ns-sym) "');")
  (emitln "goog.require('cljs.core');")
  (doseq [[sym value] table]
    (let [ns (namespace sym) name (name sym)]
      (emits "cljs.core." value " = ")
      (cond
        (keyword? sym) (emits-keyword sym)
        (symbol? sym) (emits-symbol sym)
        :else (throw
                (ex-info
                  (str "Cannot emit constant for type " (type sym))
                  {:error :invalid-constant-type 
                   :clojure.error/phase :compilation})))
      (emits ";\n"))))
(defn compile-file
  "Compiles src to a file of the same name, but with a .js extension,\n      in the src file's directory.\n\n      With dest argument, write file to provided location. If the dest\n      argument is a file outside the source tree, missing parent\n      directories will be created. The src file will only be compiled if\n      the dest file has an older modification time.\n\n      Both src and dest may be either a String or a File.\n\n      Returns a map containing {:ns .. :provides .. :requires .. :file ..}.\n      If the file was not compiled returns only {:file ...}"
  ([src]
    (let [dest (rename-to-js src)]
      (compile-file
        src
        dest
        (when env/*compiler*
          (:options (clojure.core/deref env/*compiler*))))))
  ([src dest]
    (compile-file
      src
      dest
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src dest opts]
    {:post [map?]}
    (binding [ana/*file-defs* (atom #{})
              ana/*unchecked-if* false
              ana/*unchecked-arrays* false
              ana/*cljs-warnings* ana/*cljs-warnings*]
      (let [nses (get
                   (clojure.core/deref env/*compiler*)
                   :cljs.analyzer/namespaces)
            src-file (io/file src)
            dest-file (io/file dest)
            opts (merge {:optimizations :none} opts)]
        (if (.exists src-file)
          (try
            (let [{ns :ns  :as ns-info} (ana/parse-ns
                                          src-file
                                          dest-file
                                          opts)
                  opts (if (and
                             (not= (util/ext src) "clj")
                             (= ns (quote cljs.core)))
                         (cond->
                           opts
                           (not (false? (:static-fns opts)))
                           (assoc :static-fns true)
                           true
                           (dissoc :checked-arrays))
                         opts)]
              (if (or
                    (requires-compilation? src-file dest-file opts)
                    (:force opts))
                (do
                  (util/mkdirs dest-file)
                  (when (and
                          (get-in nses [ns :defs])
                          (not= (quote cljs.core) ns)
                          (not= :interactive (:mode opts)))
                    (swap!
                      env/*compiler*
                      update-in
                      [:cljs.analyzer/namespaces]
                      dissoc
                      ns))
                  (let [[ret recompiled?] (compile-file*
                                            src-file
                                            dest-file
                                            opts)]
                    (when (and *recompiled* recompiled?)
                      (swap! *recompiled* conj ns))
                    ret))
                (do
                  (when (or
                          (and
                            (= ns (quote cljs.loader))
                            (not (contains? opts :cache-key)))
                          (and
                            (true? (:optimize-constants opts))
                            (nil? (get-in nses [ns :defs]))))
                    (with-core-cljs
                      opts
                      (fn [] (ana/analyze-file src-file opts))))
                  (assoc ns-info :out-file (.toString dest-file)))))
            (catch
              Exception
              e
              (throw
                (ex-info
                  (str "failed compiling file:" src)
                  {:file src  :clojure.error/phase :compilation}
                  e))))
          (throw
            (util/compilation-error
              (java.io.FileNotFoundException.
                (str "The file " src " does not exist.")))))))))
(defn truthy-constant? [expr]
  (let [{:keys [op form const-expr]} (ana/unwrap-quote expr)]
    (or
      (and
        (= op :const)
        form
        (not
          (or
            (and (string? form) (= form ""))
            (and (number? form) (zero? form)))))
      (and (some? const-expr) (truthy-constant? const-expr)))))
(defn emit-constant-no-meta [x]
  (cond
    (seq? x) (emit-list x emit-constants-comma-sep)
    (record? x) (let [[ns name] (ana/record-ns+name x)]
                  (emit-record-value
                    ns
                    name
                    (fn* [] (emit-constant (into {} x)))))
    (map? x) (emit-map
               (keys x)
               (vals x)
               emit-constants-comma-sep
               all-distinct?)
    (vector? x) (emit-vector x emit-constants-comma-sep)
    (set? x) (emit-set x emit-constants-comma-sep all-distinct?)
    :else (emit-constant* x)))
(defn compile-file*
  ([src dest]
    (compile-file*
      src
      dest
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src dest opts]
    (ensure
      (with-core-cljs
        opts
        (fn []
          (when (and
                  (or ana/*verbose* (:verbose opts))
                  (not (:compiler-stats opts)))
            (util/debug-prn "Compiling" (str src) "to" (str dest)))
          (util/measure
            (and
              (or ana/*verbose* (:verbose opts))
              (:compiler-stats opts))
            (str "Compiling " (str src) " to " (str dest))
            (let [ext (util/ext src)
                  {:keys [ns]  :as ns-info} (ana/parse-ns src)]
              (if-let [cached (cached-core ns ext opts)]
                [(emit-cached-core src dest cached opts) false]
                (let [opts (if (macro-ns? ns ext opts)
                             (assoc opts :macros-ns true)
                             opts)
                      dest-exists? (.exists dest)
                      ret [(emit-source src dest ext opts)
                           dest-exists?]]
                  (.setLastModified dest (util/last-modified src))
                  ret)))))))))
(defmethod
  emit*
  :case
  [{v :test  :keys [nodes default env]}]
  (when (= (:context env) :expr) (emitln "(function(){"))
  (let [gs (gensym "caseval__")]
    (when (= :expr (:context env)) (emitln "var " gs ";"))
    (emitln "switch (" v ") {")
    (doseq [{ts :tests  {:keys [then]} :then} nodes]
      (doseq [test (map :test ts)] (emitln "case " test ":"))
      (if (= :expr (:context env)) (emitln gs "=" then) (emitln then))
      (emitln "break;"))
    (when default
      (emitln "default:")
      (if (= :expr (:context env))
        (emitln gs "=" default)
        (emitln default)))
    (emitln "}")
    (when (= :expr (:context env)) (emitln "return " gs ";})()"))))
(defn emit-source-map [src dest sm-data opts]
  (let [sm-file (io/file (str (.getPath dest) ".map"))]
    (if-let [smap (:source-map-asset-path opts)]
      (emitln
        "\n//# sourceMappingURL="
        smap
        (string/replace
          (util/path sm-file)
          (str (util/path (io/file (:output-dir opts))))
          "")
        (if (true? (:source-map-timestamp opts))
          (str
            (if-not (string/index-of smap "?") "?" "&")
            "rel="
            (System/currentTimeMillis))
          ""))
      (emitln
        "\n//# sourceMappingURL="
        (or (:source-map-url opts) (.getName sm-file))
        (if (true? (:source-map-timestamp opts))
          (str "?rel=" (System/currentTimeMillis))
          "")))
    (spit
      sm-file
      (sm/encode
        {(url-path src) (:source-map sm-data)}
        {:lines (+ (:gen-line sm-data) 2) 
         :file (url-path dest) 
         :source-map-path (:source-map-path opts) 
         :source-map-timestamp (:source-map-timestamp opts) 
         :source-map-pretty-print (:source-map-pretty-print opts) 
         :relpaths
         {(util/path src)
          (util/ns->relpath (first (:provides opts)) (:ext opts))}}))))
(defn with-core-cljs
  "Ensure that core.cljs has been loaded."
  ([]
    (with-core-cljs
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([opts] (with-core-cljs opts (fn [])))
  ([opts body]
    {:pre [(or (nil? opts) (map? opts)) (fn? body)]}
    (when-not (get-in
                (clojure.core/deref env/*compiler*)
                [:cljs.analyzer/namespaces (quote cljs.core) :defs])
      (ana/analyze-file "cljs/core.cljs" opts))
    (body)))
(defn falsey-constant? [expr]
  (let [{:keys [op form const-expr]} (ana/unwrap-quote expr)]
    (or
      (and (= op :const) (or (false? form) (nil? form)))
      (and (some? const-expr) (falsey-constant? const-expr)))))
(defn compiled-by-string
  ([]
    (compiled-by-string
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([opts]
    (str
      "// Compiled by ClojureScript "
      (util/clojurescript-version)
      (when opts
        (str " " (pr-str (ana/build-affecting-options opts)))))))
(defn get-define [mname jsdoc]
  (let [opts (get (clojure.core/deref env/*compiler*) :options)]
    (and
      (some (fn* [p1__5534#] (.startsWith p1__5534# "@define")) jsdoc)
      opts
      (= (:optimizations opts) :none)
      (let [define (get-in opts [:closure-defines (str mname)])]
        (when (valid-define-value? define) (pr-str define))))))
(defn rename-to-js
  "Change the file extension from .cljs to .js. Takes a File or a\n     String. Always returns a String."
  [file-str]
  (cond
    (.endsWith file-str ".cljs") (clojure.string/replace
                                   file-str
                                   #"\.cljs$"
                                   ".js")
    (.endsWith file-str ".cljc") (if
                                   (= "cljs/core.cljc" file-str)
                                   "cljs/core$macros.js"
                                   (clojure.string/replace
                                     file-str
                                     #"\.cljc$"
                                     ".js"))
    :else (throw
            (util/compilation-error
              (IllegalArgumentException.
                (str "Invalid source file extension " file-str))))))
(defmethod
  emit-constant*
  java.time.Instant
  [inst]
  (emit-inst (.toEpochMilli inst)))
(defmethod
  emit-constant*
  java.util.Date
  [date]
  (emit-inst (.getTime date)))
(defmethod
  emit-constant*
  clojure.lang.BigInt
  [x]
  (emits (.doubleValue x)))
(defmethod emit-constant* BigDecimal [x] (emits (.doubleValue x)))
(defmethod
  emit-constant*
  java.util.UUID
  [uuid]
  (let [uuid-str (.toString uuid)]
    (emits
      "new cljs.core.UUID(\""
      uuid-str
      "\", "
      (hash uuid-str)
      ")")))
(defmethod
  emit-constant*
  JSValue
  [v]
  (let [items (.-val v)]
    (if (map? items)
      (emit-js-object
        items
        (fn* [p1__5279#] (fn [] (emit-constant p1__5279#))))
      (emit-js-array items emit-constants-comma-sep))))
(defn valid-define-value? [x]
  (or (string? x) (true? x) (false? x) (number? x)))
(defn resolve-type [env t]
  (cond
    (get base-types t) t
    (get mapped-types t) (get mapped-types t)
    (.startsWith t "!") (str "!" (resolve-type env (subs t 1)))
    (.startsWith t "{") t
    (.startsWith t "function") (let 
                                 [idx (.lastIndexOf t ":")
                                  [fstr rstr]
                                  (if-not
                                    (== -1 idx)
                                    [(subs t 0 idx)
                                     (subs t (inc idx) (count t))]
                                    [t nil])
                                  ret-t
                                  (when rstr (resolve-type env rstr))
                                  axstr
                                  (subs fstr 9 (dec (count fstr)))
                                  args-ts
                                  (when-not
                                    (string/blank? axstr)
                                    (map
                                      (comp
                                        (fn*
                                          [p1__5485#]
                                          (resolve-type env p1__5485#))
                                        string/trim)
                                      (string/split axstr #",")))]
                                 (cond->
                                   (str
                                     "function("
                                     (string/join "," args-ts)
                                     ")")
                                   ret-t
                                   (str ":" ret-t)))
    (.endsWith t "=") (str
                        (resolve-type env (subs t 0 (dec (count t))))
                        "=")
    :else (munge (str (:name (ana/resolve-var env (symbol t)))))))
(defn emit-record-value [ns name items]
  (emits ns ".map__GT_" name "(" items ")"))
(defn munge-param-return [env line]
  (cond
    (re-find #"@param" line) (let [[p ts n & xs]
                                   (map
                                     string/trim
                                     (string/split
                                       (string/trim line)
                                       #" "))]
                               (if
                                 (and
                                   (= "@param" p)
                                   ts
                                   (.startsWith ts "{"))
                                 (string/join
                                   " "
                                   (concat
                                     [p
                                      (resolve-types env ts)
                                      (munge n)]
                                     xs))
                                 line))
    (re-find #"@return" line) (let [[p ts & xs]
                                    (map
                                      string/trim
                                      (string/split
                                        (string/trim line)
                                        #" "))]
                                (if
                                  (and
                                    (= "@return" p)
                                    ts
                                    (.startsWith ts "{"))
                                  (string/join
                                    " "
                                    (concat
                                      [p (resolve-types env ts)]
                                      xs))
                                  line))
    :else line))
(defn compile-root
  "Looks recursively in src-dir for .cljs files and compiles them to\n      .js files. If target-dir is provided, output will go into this\n      directory mirroring the source directory structure. Returns a list\n      of maps containing information about each file which was compiled\n      in dependency order."
  ([src-dir] (compile-root src-dir "out"))
  ([src-dir target-dir]
    (compile-root
      src-dir
      target-dir
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src-dir target-dir opts]
    (swap! env/*compiler* assoc :root src-dir)
    (let [src-dir-file (io/file src-dir)
          inputs (deps/dependency-order
                   (map
                     (fn* [p1__6062#] (ana/parse-ns p1__6062#))
                     (cljs-files-in src-dir-file)))]
      (binding [*inputs* (zipmap (map :ns inputs) inputs)]
        (loop [inputs (seq inputs) compiled []]
          (if inputs
            (let [{:keys [source-file]  :as ns-info} (first inputs)
                  output-file (util/to-target-file target-dir ns-info)
                  ijs (compile-file source-file output-file opts)]
              (recur
                (next inputs)
                (conj
                  compiled
                  (assoc ijs :file-name (.getPath output-file)))))
            compiled))))))
(defn emit-cached-core [src dest cached opts]
  (when (or ana/*verbose* (:verbose opts))
    (util/debug-prn "Using cached cljs.core" (str src)))
  (spit dest (slurp cached))
  (.setLastModified dest (util/last-modified src))
  (when (true? (:source-map opts))
    (spit
      (io/file (str dest ".map"))
      (json/write-str
        (assoc
          (json/read-str (slurp (io/resource "cljs/core.aot.js.map")))
          "file"
          (str
            (io/file
              (util/output-directory opts)
              "cljs"
              "core.js"))))))
  (merge (ana/parse-ns src dest nil) {:out-file dest}))
(defn resolve-types [env ts]
  (let [ts (-> ts string/trim (subs 1 (dec (count ts))))
        xs (string/split ts #"\|")]
    (str
      "{"
      (string/join
        "|"
        (map (fn* [p1__5493#] (resolve-type env p1__5493#)) xs))
      "}")))
(defn- emit-inst [inst-ms] (emits "new Date(" inst-ms ")"))
(defn emit-str [expr] (with-out-str (emit expr)))
cljs.closure-tests 0/1 (0.0%)
(defn empty-handler [warning-type env extra])
cljs.analyzer-tests 51/51 (100.0%)
(defn analyze-forms [cenv xs]
  (binding [ana/*unchecked-if* false ana/*analyze-deps* false]
    (env/with-compiler-env cenv (ana/analyze-form-seq xs))))
(defn prs-ana [fstr]
  (env/with-compiler-env
    analyze-ops-cenv
    (let [[form] (ana/forms-seq* (java.io.StringReader. fstr))]
      (ana' form))))
(defn ana' [form]
  (env/with-compiler-env analyze-ops-cenv (analyze test-env form)))
(defn warn-count [form]
  (let [counter (atom 0)
        tracker (fn [warning-type env & [extra]]
                  (when (warning-type ana/*cljs-warnings*)
                    (swap! counter inc)))]
    (ana/with-warning-handlers
      [tracker]
      (analyze (ana/empty-env) form))
    (clojure.core/deref counter)))
(defn core-env [] (atom (clojure.core/deref test-core-env)))
(clojure.core/defn ana
  ([&form &env form]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.analyzer-tests/ana'))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote quote))
              (clojure.core/list form))))))))
cljs.analyzer 7834/9081 (86.3%)
(defmethod
  parse
  (quote let*)
  [op encl-env form _ _]
  (analyze-let encl-env form false nil))
(defmethod
  build-dot-form
  [:cljs.analyzer/expr :cljs.analyzer/symbol :cljs.analyzer/expr]
  [[target meth args]]
  (build-method-call target meth args))
(defn analyze-seq*-wrap [op env form name opts]
  (wrapping-errors env (analyze-seq* op env form name opts)))
(defmethod
  resolve*
  :js
  [env sym full-ns current-ns]
  {:name (symbol (str full-ns) (str (name sym))) 
   :op :js-var 
   :ns full-ns})
(defn analyze-let-binding-init [env init loop-lets]
  (binding [*loop-lets* loop-lets] (analyze env init)))
(defmethod
  parse
  (quote case*)
  [op env [_ sym tests thens default :as form] name _]
  (assert (symbol? sym) "case* must switch on symbol")
  (assert
    (every? vector? tests)
    "case* tests must be grouped in vectors")
  (let [expr-env (assoc env :context :expr)
        v (disallowing-recur (analyze expr-env sym))
        tests (mapv
                (fn*
                  [p1__3236#]
                  (mapv (fn [t] (analyze expr-env t)) p1__3236#))
                tests)
        thens (mapv (fn* [p1__3237#] (analyze env p1__3237#)) thens)
        nodes (mapv
                (fn [tests then]
                  {:op :case-node 
                   :env env 
                   :tests
                   (mapv
                     (fn [test]
                       {:op :case-test 
                        :form (:form test) 
                        :env expr-env 
                        :test test 
                        :children [:test]})
                     tests) 
                   :then
                   {:op :case-then 
                    :form (:form then) 
                    :env env 
                    :then then 
                    :children [:then]} 
                   :children [:tests :then]})
                tests
                thens)
        default (analyze env default)]
    (assert
      (every?
        (fn [t]
          (or
            (-> t :info :const)
            (and
              (= :const (:op t))
              ((some-fn number? string? char?) (:form t)))))
        (apply concat tests))
      "case* tests must be numbers, strings, or constants")
    {:env env 
     :op :case 
     :form form 
     :test v 
     :nodes nodes 
     :default default 
     :children [:test :nodes :default]}))
(defn munge-node-lib [name]
  (str
    "node$module$"
    (munge (string/replace (str name) #"[.\/]" "\\$"))))
(defn extern-pre [sym current-ns]
  (let [pre (into
              (quote [Object])
              (->> (string/split (name sym) #"\.") (map symbol) vec))]
    (when-not (has-extern? pre)
      (swap!
        env/*compiler*
        update-in
        (into [:cljs.analyzer/namespaces current-ns :externs] pre)
        merge
        {}))
    pre))
(defn- accumulating-warning-handler [warn-acc]
  (fn [warning-type env extra]
    (when (warning-type *cljs-warnings*)
      (swap! warn-acc conj [warning-type env extra]))))
(clojure.core/defn all-warn
  ([&form &env & body]
    (let [all-warnings (zipmap (keys *cljs-warnings*) (repeat true))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/binding))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote cljs.analyzer/*cljs-warnings*))
                  (clojure.core/list all-warnings)))))
          body)))))
(defmethod
  parse
  (quote quote)
  [_ env [_ x :as form] _ _]
  (when (not= 2 (count form))
    (throw (error env "Wrong number of args to quote")))
  (let [expr (analyze-const env x)]
    {:op :quote 
     :expr expr 
     :env env 
     :form form 
     :tag (:tag expr) 
     :children [:expr]}))
(defn js-var-fn? [fn-ast] (js-var? (:info fn-ast)))
(defn goog-module-dep? [module]
  (let [[module _] (lib&sublib module)
        module-str (str module)
        options (compiler-options)]
    (if (and
          (:global-goog-object&array options)
          (#{"goog.array" "goog.object"} module-str))
      false
      (=
        :goog
        (get-in
          (clojure.core/deref env/*compiler*)
          [:js-dependency-index module-str :module])))))
(defn- error-data
  ([env phase] (error-data env phase nil))
  ([env phase symbol]
    (merge
      (-> (source-info env) source-info->error-data)
      {:clojure.error/phasephase}(when    symbol{:clojure.error/symbolsymbol}) )))
(defn get-expander
  "Given a sym, a symbol identifying a macro, and env, an analysis environment\n   return the corresponding Clojure macroexpander."
  [sym env]
  (let [mvar (get-expander* sym env)]
    (when (and (some? mvar) (.isMacro mvar)) mvar)))
(defn munge-goog-module-lib
  ([name]
    (str
      "goog$module$"
      (munge (string/replace (str name) #"[.\/]" "\\$"))))
  ([ns name] (str (munge ns) "." (munge-goog-module-lib name))))
(defmethod
  error-message
  :overload-arity
  [warning-type info]
  (str (:name info) ": Can't have 2 overloads with same arity"))
(defn parse-type [op env [_ tsym fields pmasks body :as form]]
  (let [t (:name (resolve-var (dissoc env :locals) tsym))
        locals (reduce
                 (fn [m fld]
                   (assoc
                     m
                     fld
                     {:name fld 
                      :field true 
                      :column (get-col fld env) 
                      :unsynchronized-mutable
                      (-> fld meta :unsynchronized-mutable) 
                      :line (get-line fld env) 
                      :tag (-> fld meta :tag) 
                      :mutable (-> fld meta :mutable) 
                      :volatile-mutable
                      (-> fld meta :volatile-mutable) 
                      :shadow (m fld) 
                      :local :field}))
                 {}
                 (if (= :defrecord op)
                   (concat fields (quote [__meta __extmap __hash]))
                   fields))
        protocols (-> tsym meta :protocols)]
    (swap!
      env/*compiler*
      update-in
      [:cljs.analyzer/namespaces (-> env :ns :name) :defs tsym]
      (fn [m]
        (let [m (assoc
                  (or m {})
                  :name
                  t
                  :tag
                  (quote function)
                  :type
                  true
                  :num-fields
                  (count fields)
                  :record
                  (= :defrecord op))]
          (merge
            m
            (dissoc (meta tsym) :protocols)
            {:protocols protocols}
            (source-info tsym env)))))
    {:children [:body] 
     :pmasks pmasks 
     :protocols (disj protocols (quote cljs.core/Object)) 
     :fields fields 
     :op op 
     :env env 
     :t t 
     :form form 
     :tag (quote function) 
     :body (analyze (assoc env :locals locals) body)}))
(defn- set-test-induced-tags
  "Looks at the test and sets any tags which are induced by virtue\n  of the test being truthy. For example in (if (string? x) x :bar)\n  the local x in the then branch must be of string type."
  [env test]
  (let [[local tag] (or
                      (simple-predicate-induced-tag env test)
                      (type-check-induced-tag env test)
                      (truth-induced-tag env test))]
    (cond-> env local (assoc-in [:locals local :tag] tag))))
(defn macro-autoload-ns?
  "Given a spec form check whether the spec namespace requires a macro file\n   of the same name. If so return true."
  [form]
  (when *macro-infer*
    (let [ns (if (sequential? form) (first form) form)
          {:keys [use-macros require-macros]} (or
                                                (get-in
                                                  (clojure.core/deref
                                                    env/*compiler*)
                                                  [:cljs.analyzer/namespaces
                                                   ns])
                                                (when-let 
                                                  [res
                                                   (util/ns->source
                                                     ns)]
                                                  (:ast
                                                    (parse-ns res))))]
      (or
        (some #{ns} (vals use-macros))
        (some #{ns} (vals require-macros))))))
(defn analyze-do-statements* [env exprs]
  (mapv
    (fn*
      [p1__3459#]
      (analyze (assoc env :context :statement) p1__3459#))
    (butlast exprs)))
(defn compiler-options []
  (get (clojure.core/deref env/*compiler*) :options))
(defn analyze-let-bindings [encl-env bindings op]
  (disallowing-recur (analyze-let-bindings* encl-env bindings op)))
(defn default-warning-handler [warning-type env extra]
  (when (warning-type *cljs-warnings*)
    (when-let [s (error-message warning-type extra)]
      (binding [*out* *err*]
        (println (message env (str "WARNING: " s)))))))
(clojure.core/defn with-warning-handlers
  ([&form &env handlers & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list
                  (quote cljs.analyzer/*cljs-warning-handlers*))
                (clojure.core/list handlers)))))
        body))))
(defn fn-ast->tag [{:keys [info]  :as fn-ast}]
  (cond
    (:fn-var info) (:ret-tag info)
    (:js-fn-var info) (:ret-tag info)
    (js-var-fn? fn-ast) (quote js)
    :else (when (= (quote js) (:ns info)) (quote js))))
(defn ast? [x] (and (map? x) (contains? x :op)))
(defn missing-rename? [sym cenv]
  (let [lib (symbol (namespace sym)) sym (symbol (name sym))]
    (missing-use? lib sym cenv)))
(defn analyze-fn-methods-pass2 [menv locals type meths]
  (analyze-fn-methods-pass2* menv locals type meths))
(defn loaded-js-ns?
  "Check if a JavaScript namespace has been loaded. JavaScript vars are\n  not currently checked."
  [env prefix]
  (when-not (gets
              (clojure.core/deref env/*compiler*)
              :cljs.analyzer/namespaces
              prefix)
    (let [ns (:ns env)]
      (or
        (some? (get (:requires ns) prefix))
        (some? (get (:imports ns) prefix))))))
(defn js-tag? [x]
  (and (symbol? x) (or (= (quote js) x) (= "js" (namespace x)))))
(defn analyze-keyword [env sym]
  (register-constant! env sym)
  {:op :const 
   :val sym 
   :env env 
   :form sym 
   :tag (quote cljs.core/Keyword)})
(defn add-consts
  "Given a compiler state and a map from fully qualified symbols to constant\n  EDN values, update the compiler state marking these vars as const to support\n  direct substitution of these vars in source."
  [compiler-state constants-map]
  (reduce-kv
    (fn [compiler-state sym value]
      (let [ns (symbol (namespace sym))]
        (update-in
          compiler-state
          [:cljs.analyzer/namespaces ns :defs (symbol (name sym))]
          merge
          {:const-expr
           (binding [*passes* (conj
                                *passes*
                                (replace-env-pass {:context :expr}))]
             (analyze (empty-env) value))})))
    compiler-state
    constants-map))
(defn intern-macros
  "Given a Clojure namespace intern all macros into the ambient ClojureScript\n   analysis environment."
  ([ns] (intern-macros ns false))
  ([ns reload]
    (when (or
            (nil?
              (gets
                (clojure.core/deref env/*compiler*)
                :cljs.analyzer/namespaces
                ns
                :macros))
            reload)
      (swap!
        env/*compiler*
        assoc-in
        [:cljs.analyzer/namespaces ns :macros]
        (->>
          (ns-interns ns)
          (filter (fn [[_ v]] (.isMacro v)))
          (map
            (fn [[k v]] [k
                         (as->
                           (meta v)
                           vm
                           (let [ns (.getName (:ns vm))]
                             (assoc
                               vm
                               :ns
                               ns
                               :name
                               (symbol (str ns) (str k))
                               :macro
                               true)))]))
          (into {}))))))
(defn analyze-fn-method-body [env form recur-frames]
  (binding [*recur-frames* recur-frames] (analyze env form)))
(defn node-module-dep? [module]
  (let [idx (get
              (clojure.core/deref env/*compiler*)
              :node-module-index)]
    (contains? idx (str (-> module lib&sublib first)))))
(defn build-affecting-options-sha [path opts]
  (let [m (assoc (build-affecting-options opts) :path path)]
    (util/content-sha (pr-str m) 7)))
(defn infer-invoke [env {fn-ast :fn  :keys [args]  :as ast}]
  (let [me (assoc (find-matching-method fn-ast args) :op :fn-method)]
    (if-some
      [ret-tag (infer-tag env me)]
      ret-tag
      (let []
        (if-some
          [ret-tag (fn-ast->tag fn-ast)]
          ret-tag
          impl/ANY_SYM)))))
(defn aliasable-clj-ns?
  "Predicate for testing with a symbol represents an aliasable clojure namespace."
  [sym]
  (when-not (util/ns->source sym)
    (let [[seg1 :as segs] (string/split (clojure.core/name sym) #"\.")]
      (when (= "clojure" seg1)
        (let [sym' (clj-ns->cljs-ns sym)] (util/ns->source sym'))))))
(defn implicit-import? [env prefix suffix]
  (contains? implicit-nses prefix))
(defn- unsorted-map? [x] (and (map? x) (not (sorted? x))))
(defmethod
  build-dot-form
  [:cljs.analyzer/expr :cljs.analyzer/property ()]
  [[target prop _]]
  {:dot-action :cljs.analyzer/access 
   :target target 
   :field (with-meta (-> prop name (.substring 1) symbol) (meta prop))})
(defmethod
  parse
  (quote var)
  [op env [_ sym :as form] _ _]
  (when (not= 2 (count form))
    (throw (error env "Wrong number of args to var")))
  (when-not (symbol? sym)
    (throw (error env "Argument to var must be symbol")))
  (merge
    {:env env  :op :the-var  :children [:var :sym :meta]  :form form}
    (var-ast env sym)))
(defn get-tag [ast]
  (if-some
    [tag (-> ast :form meta :tag)]
    tag
    (if-some [tag (-> ast :tag)] tag (-> ast :info :tag))))
(defn missing-renames [renames env]
  (let [cenv (clojure.core/deref env/*compiler*)]
    (into
      {}
      (filter
        (fn [[_ qualified-sym]] (missing-rename? qualified-sym cenv))
        renames))))
(defn lib&sublib
  "If a library name has the form foo$bar, return a vector of the library and\n   the sublibrary property."
  [lib]
  (if-let [xs (re-matches #"(.*)\$(.*)" (str lib))]
    (drop 1 xs)
    [lib nil]))
(defn confirm-var-exist-warning [env prefix suffix]
  (fn [env prefix suffix]
    (warning
      :undeclared-var
      env
      {:prefix prefix 
       :suffix suffix 
       :macro-present?
       (not
         (nil?
           (get-expander (symbol (str prefix) (str suffix)) env)))})))
(defn- record-basis [tag]
  (let [positional-factory (symbol (str "->" (name tag)))
        fields (first
                 (get-in
                   (clojure.core/deref env/*compiler*)
                   [:cljs.analyzer/namespaces
                    (symbol (namespace tag))
                    :defs
                    positional-factory
                    :method-params]))]
    (into #{} fields)))
(defn unwrap-quote [{:keys [op]  :as ast}]
  (if (= op :quote) (:expr ast) ast))
(defn foreign-dep? [dep]
  (let [js-index (:js-dependency-index
                   (clojure.core/deref env/*compiler*))]
    (if-some
      [[_ {:keys [foreign]}]
       (find js-index (name (-> dep lib&sublib first)))]
      foreign
      false)))
(defn parse-invoke [env form]
  (disallowing-recur (parse-invoke* env form)))
(defmethod
  build-dot-form
  [:cljs.analyzer/expr :cljs.analyzer/symbol ()]
  [[target meth args]]
  (build-method-call target meth args))
(defmethod
  parse
  (quote do)
  [op env [_ & exprs :as form] _ _]
  (let [statements (analyze-do-statements env exprs)]
    (if (<= (count exprs) 1)
      (let [ret (analyze env (first exprs))
            children [:statements :ret]]
        {:op :do 
         :env env 
         :form form 
         :statements statements 
         :ret ret 
         :children children})
      (let [ret-env (if (= :statement (:context env))
                      (assoc env :context :statement)
                      (assoc env :context :return))
            ret (analyze ret-env (last exprs))
            children [:statements :ret]]
        {:op :do 
         :env env 
         :form form 
         :statements statements 
         :ret ret 
         :children children}))))
(defn checked-arrays
  "Returns false-y, :warn, or :error based on configuration and the\n   current value of *unchecked-arrays*."
  []
  (when (and
          (not= :advanced (:optimizations (compiler-options)))
          (not *unchecked-arrays*))
    *checked-arrays*))
(defmethod
  build-dot-form
  [:cljs.analyzer/expr :cljs.analyzer/list ()]
  [[target meth-expr _]]
  (build-method-call target (first meth-expr) (rest meth-expr)))
(defn prim-ctor?
  "Test whether a tag is a constructor for a JS primitive"
  [t]
  (contains? js-prim-ctor->tag t))
(defn analyze-set [env form]
  (let [expr-env (assoc env :context :expr)
        items (disallowing-recur
                (mapv
                  (fn* [p1__4259#] (analyze expr-env p1__4259#))
                  form))]
    (analyze-wrap-meta
      {:op :set 
       :env env 
       :form form 
       :items items 
       :children [:items] 
       :tag (quote cljs.core/ISet)})))
(clojure.core/defn disallowing-ns*
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.analyzer/*allow-ns*))
                (clojure.core/list (quote false))))))
        body))))
(defn elide-reader-meta [m]
  (dissoc m :file :line :column :end-column :end-line :source))
(defmethod
  error-message
  :invalid-arithmetic
  [warning-type info]
  (str
    (:js-op info)
    ", all arguments must be numbers, got "
    (:types info)
    " instead"))
(defn analyze
  "Given an environment, a map containing {:locals (mapping of names to bindings), :context\n  (one of :statement, :expr, :return), :ns (a symbol naming the\n  compilation ns)}, and form, returns an expression object (a map\n  containing at least :form, :op and :env keys). If expr has any (immediately)\n  nested exprs, must have a :children entry. This must be a vector of keywords naming\n  the immediately nested fields mapped to an expr or vector of exprs. This will\n  facilitate code walking without knowing the details of the op set."
  ([env form] (analyze env form nil))
  ([env form name]
    (analyze
      env
      form
      name
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([env form name opts]
    (wrapping-errors
      env
      (if (analyzed? form)
        (no-warn (analyze* env form name opts))
        (analyze* env form name opts)))))
(defn ns->module-type [ns]
  (cond
    (goog-module-dep? ns) :goog-module
    (js-module-exists? ns) :js
    (node-module-dep? ns) :node
    (dep-has-global-exports? ns) :global))
(defn get-aliases
  "Get all alias maps for a namespace."
  [ns]
  (apply
    merge
    ((juxt :requires :require-macros :as-aliases) (get-namespace ns))))
(defn resolve-ns-alias
  ([env name] (resolve-ns-alias env name (symbol name)))
  ([env name not-found]
    (let [sym (symbol name)]
      (get (:requires (:ns env)) sym not-found))))
(defn- analyze-fn-method [env locals form type analyze-body?]
  (let [param-names (first form)
        variadic (boolean (some (quote #{&}) param-names))
        param-names (vec (remove (quote #{&}) param-names))
        body (next form)
        step (analyze-fn-method-param env)
        step-init [locals []]
        [locals params] (reduce
                          step
                          step-init
                          (map-indexed vector param-names))
        params' (if (true? variadic) (butlast params) params)
        fixed-arity (count params')
        recur-frame {:protocol-impl (:protocol-impl env) 
                     :params params 
                     :flag (atom nil) 
                     :tags (atom [])}
        recur-frames (cons recur-frame *recur-frames*)
        body-env (assoc env :context :return :locals locals)
        body-form (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote do))
                      body))
        expr (when analyze-body?
               (analyze-fn-method-body
                 body-env
                 body-form
                 recur-frames))
        recurs (clojure.core/deref (:flag recur-frame))]
    (merge
      {:env env 
       :op :fn-method 
       :variadic? variadic 
       :params params 
       :fixed-arity fixed-arity 
       :type type 
       :form form 
       :recurs recurs}
      (if (some? expr)
        {:body (assoc expr :body? true)  :children [:params :body]}
        {:children [:params]}))))
(defn var-meta
  ([var] (var-meta var nil))
  ([var expr-env]
    (let [sym (:name var)
          ks [:ns :doc :file :line :column]
          m (merge
              (let [user-meta (:meta var) uks (keys user-meta)]
                (zipmap
                  uks
                  (map
                    (fn*
                      [p1__3174#]
                      (list (quote quote) (get user-meta p1__3174#)))
                    uks)))
              (assoc
                (zipmap
                  ks
                  (map
                    (fn*
                      [p1__3175#]
                      (list (quote quote) (get var p1__3175#)))
                    ks))
                :name
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote quote))
                    (clojure.core/list (symbol (name (:name var))))))
                :test
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/when))
                    (clojure.core/list sym)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote .-cljs$lang$test))
                          (clojure.core/list sym))))))
                :arglists
                (let [arglists (:arglists var)
                      arglists' (if
                                  (= (quote quote) (first arglists))
                                  (second arglists)
                                  arglists)]
                  (list
                    (quote quote)
                    (doall
                      (map
                        with-meta
                        arglists'
                        (:arglists-meta var)))))))]
      (if expr-env (analyze expr-env m) m))))
(defn fn-name-var [env locals name]
  (when (some? name)
    (let [ns (-> env :ns :name)
          shadow (or
                   (handle-symbol-local name (get locals name))
                   (get-in env [:js-globals name]))
          fn-scope (:fn-scope env)
          name-var {:name name 
                    :op :binding 
                    :local :fn 
                    :info
                    {:fn-self-name true 
                     :fn-scope fn-scope 
                     :ns ns 
                     :shadow shadow}}
          tag (-> name meta :tag)
          ret-tag (when (some? tag) {:ret-tag tag})]
      (merge name-var ret-tag))))
(defn infer-type [env {:keys [tag]  :as ast} _]
  (if (or (nil? tag) (= (quote function) tag))
    (if (= :fn (:op ast))
      (update
        ast
        :methods
        (fn [ms]
          (into
            []
            (map (fn* [p1__4290#] (infer-type env p1__4290# _)))
            ms)))
      (if-some [tag (infer-tag env ast)] (assoc ast :tag tag) ast))
    ast))
(defn dotted-symbol? [sym]
  (let [s (str sym)] (and (.contains s ".") (not (.contains s "..")))))
(defn analyzed
  "Mark a form as being analyzed. Assumes x satisfies IMeta. Useful to suppress\n  warnings that will have been caught by a first compiler pass."
  [x]
  (cond
    (unsorted-map? x) (assoc x :cljs.analyzer/analyzed true)
    :else (vary-meta x assoc :cljs.analyzer/analyzed true)))
(defn has-error-data? [ex]
  (contains? (ex-data ex) :clojure.error/phase))
(defn get-js-tag [form]
  (let [form-meta (meta form)]
    (if-some
      [tag (:tag form-meta)]
      tag
      (when (true? (:numeric form-meta)) (quote number)))))
(defn get-externs []
  (:cljs.analyzer/externs (clojure.core/deref env/*compiler*)))
(defn analyze-list [env form]
  (let [expr-env (assoc env :context :expr)
        items (disallowing-recur
                (mapv
                  (fn* [p1__4247#] (analyze expr-env p1__4247#))
                  form))]
    (analyze-wrap-meta
      {:op :list 
       :env env 
       :form form 
       :items items 
       :children [:items] 
       :tag (quote cljs.core/IList)})))
(defn message [env s]
  (str
    s
    (if (:line env)
      (str " at line " (:line env) " " *cljs-file*)
      (when *cljs-file* (str " in file " *cljs-file*)))))
(defn- valid-arity? [argc method-params]
  (or
    (nil? method-params)
    (boolean (some #{argc} (map count method-params)))))
(defn js-module-exists? [module]
  (js-module-exists?*
    (get-in (clojure.core/deref env/*compiler*) [:js-module-index])
    module))
(defn analyze-let-body [env context exprs recur-frames loop-lets]
  (binding [*recur-frames* recur-frames *loop-lets* loop-lets]
    (analyze-let-body* env context exprs)))
(defn get-data-readers*
  "returns a merged map containing all data readers defined by libraries\n      on the classpath."
  ([]
    (get-data-readers*
      (. (Thread/currentThread) (getContextClassLoader))))
  ([classloader]
    (let [data-reader-urls (enumeration-seq
                             (. classloader
                              (getResources "data_readers.cljc")))]
      (reduce load-data-reader-file {} data-reader-urls))))
(defn ensure-defs
  "Ensures that a non-nil defs map exists in the compiler state for a given\n  ns. (A non-nil defs map signifies that the namespace has been analyzed.)"
  [ns]
  (swap!
    env/*compiler*
    update-in
    [:cljs.analyzer/namespaces ns :defs]
    (fn* [p1__4516#] (or p1__4516# {}))))
(defn find-matching-method [fn-ast params]
  (let [methods (or (:methods fn-ast) (-> fn-ast :info :methods))
        c (count params)]
    (some
      (fn [m] (and (or (== (:fixed-arity m) c) (:variadic? m)) m))
      methods)))
(defn analyze-vector [env form]
  (let [expr-env (assoc env :context :expr)
        items (disallowing-recur
                (mapv
                  (fn* [p1__4253#] (analyze expr-env p1__4253#))
                  form))]
    (analyze-wrap-meta
      {:op :vector 
       :env env 
       :form form 
       :items items 
       :children [:items] 
       :tag (quote cljs.core/IVector)})))
(defn munge-global-export [name]
  (str
    "global$module$"
    (munge (string/replace (str name) #"[.\/]" "\\$"))))
(defn missing-rename-macro? [sym]
  (let [lib (symbol (namespace sym))
        sym (symbol (name sym))
        the-ns (find-ns lib)]
    (or (nil? the-ns) (nil? (.findInternedVar the-ns sym)))))
(defn analyze-do-statements [env exprs]
  (disallowing-recur (analyze-do-statements* env exprs)))
(defn analyze-js-star [env jsform args form]
  (disallowing-recur (analyze-js-star* env jsform args form)))
(defn missing-use-macro? [lib sym]
  (when (symbol? lib)
    (let [the-ns (find-ns lib)]
      (or (nil? the-ns) (nil? (.findInternedVar the-ns sym))))))
(defmethod
  error-message
  :declared-arglists-mismatch
  [warning-type info]
  (str
    (symbol (str (:ns-name info)) (str (:sym info)))
    " declared arglists "
    (:declared info)
    " mismatch defined arglists "
    (:defined info)))
(defmethod
  error-message
  :non-dynamic-earmuffed-var
  [warning-type {:keys [var]  :as info}]
  (str
    var
    " not declared dynamic and thus is not dynamically rebindable, but its name "
    "suggests otherwise. Please either indicate ^:dynamic "
    var
    " or change the name"))
(defn process-rewrite-form [[k & specs :as form]]
  (letfn
    [(process-spec
       [maybe-spec]
       (let [[lib & xs] (if (sequential? maybe-spec)
                          maybe-spec
                          [maybe-spec])]
         (if (and (symbol? lib) (aliasable-clj-ns? lib))
           (let [lib' (clj-ns->cljs-ns lib) spec (cons lib' xs)]
             (into (if xs [spec] []) [(list lib' :as lib)]))
           [maybe-spec])))]
    (if (#{:use :require} k)
      (cons k (mapcat process-spec specs))
      form)))
(defn warning [warning-type env extra]
  (doseq [handler *cljs-warning-handlers*]
    (handler warning-type env extra)))
(defn- source-path
  "Returns a path suitable for providing to tools.reader as a 'filename'."
  [x]
  (cond (instance? File x) (.getAbsolutePath x) :default (str x)))
(defn has-extern?
  ([pre] (has-extern? pre (get-externs)))
  ([pre externs]
    (or
      (has-extern?* pre externs)
      (when (= 1 (count pre))
        (let [x (first pre)]
          (or
            (get-in externs (conj (quote [Window prototype]) x))
            (get-in externs (conj (quote [Number]) x)))))
      (-> (last pre) str (string/starts-with? "cljs$")))))
(defmethod
  error-message
  :variadic-max-arity
  [warning-type info]
  (str
    (:name info)
    ": Can't have fixed arity function with more params than variadic function"))
(defmethod
  error-message
  :infer-warning
  [warning-type {:keys [warn-type form type property]}]
  (case
    warn-type
    :target
    (str "Cannot infer target type in expression " form "")
    :property
    (str
      "Cannot resolve property "
      property
      " for inferred type "
      type
      " in expression "
      form)
    :object
    (str
      "Adding extern to Object for property "
      property
      " due to "
      "ambiguous expression "
      form)))
(defmethod
  parse
  (quote new)
  [_ env [_ ctor & args :as form] _ _]
  (disallowing-recur
    (let [enve (assoc env :context :expr)
          ctorexpr (analyze enve ctor)
          ctor-var (when (#{:var :js-var :local} (:op ctorexpr))
                     (resolve-existing-var env ctor))
          record-args (when (and
                              (:record ctor-var)
                              (not (-> ctor meta :internal-ctor)))
                        (repeat 3 (analyze enve nil)))
          argexprs (into
                     (vec
                       (map
                         (fn* [p1__3549#] (analyze enve p1__3549#))
                         args))
                     record-args)
          known-num-fields (:num-fields ctor-var)
          argc (count args)]
      (when (and
              (not (-> ctor meta :internal-ctor))
              (some? known-num-fields)
              (not
                (or
                  (= known-num-fields argc)
                  (and
                    (:record ctor-var)
                    (= (+ 2 known-num-fields) argc)))))
        (warning :fn-arity env {:argc argc  :ctor ctor}))
      {:env env 
       :op :new 
       :form form 
       :class ctorexpr 
       :args argexprs 
       :children [:class :args] 
       :tag
       (let [tag (-> ctorexpr :info :tag)]
         (if (and (js-tag? tag) (not (prim-ctor? tag)))
           (quote js)
           (let [name (-> ctorexpr :info :name)]
             (or (js-prim-ctor->tag name) name))))})))
(defn rewrite-cljs-aliases
  "Alias non-existing clojure.* namespaces to existing cljs.* namespaces if\n      possible."
  [args]
  (map process-rewrite-form args))
(defn canonicalize-specs [specs]
  (letfn
    [(canonicalize
       [quoted-spec-or-kw]
       (if (keyword? quoted-spec-or-kw)
         quoted-spec-or-kw
         (as->
           (second quoted-spec-or-kw)
           spec
           (if (or (vector? spec) (map? spec)) spec [spec]))))]
    (map canonicalize specs)))
(defn forms-seq*
  "Seq of Clojure/ClojureScript forms from rdr, a java.io.Reader. Optionally\n     accepts a filename argument which will be used in any emitted errors."
  ([rdr] (forms-seq* rdr nil))
  ([rdr filename]
    {:pre [(instance? Reader rdr)]}
    (let [eof-sentinel (Object.)
          opts (merge
                 {:eof eof-sentinel}
                 (if (and filename (= (util/ext filename) "cljc"))
                   {:read-cond :allow  :features #{:cljs}}))
          pbr (readers/indexing-push-back-reader
                (PushbackReader. rdr)
                1
                filename)
          data-readers (merge
                         tags/*cljs-data-readers*
                         (load-data-readers))
          forms-seq_ (fn forms-seq_ []
                       (lazy-seq
                         (let [form (binding 
                                      [*ns* (create-ns *cljs-ns*)
                                       reader/*data-readers*
                                       data-readers
                                       reader/*alias-map*
                                       (get-aliases *cljs-ns*)
                                       reader/resolve-symbol
                                       resolve-symbol]
                                      (reader/read opts pbr))]
                           (if (identical? form eof-sentinel)
                             (.close rdr)
                             (cons form (forms-seq_))))))]
      (forms-seq_))))
(defn empty-env
  "Construct an empty analysis environment. Required to analyze forms."
  []
  (ensure
    {:ns (get-namespace *cljs-ns*) 
     :context :statement 
     :locals {} 
     :fn-scope [] 
     :js-globals
     (into
       {}
       (map
         (fn*
           [p1__2914#]
           (vector
             p1__2914#
             {:op :js-var  :name p1__2914#  :ns (quote js)}))
         (quote
           (alert
             window
             document
             console
             escape
             unescape
             screen
             location
             navigator
             history
             location
             global
             process
             require
             module
             exports))))}))
(defn missing-uses [uses env]
  (let [cenv (clojure.core/deref env/*compiler*)]
    (into
      {}
      (filter (fn [[sym lib]] (missing-use? lib sym cenv)) uses))))
(defn used? [env sym]
  (or
    (some? (gets env :ns :use-macros sym))
    (some?
      (gets
        (clojure.core/deref env/*compiler*)
        :cljs.analyzer/namespaces
        (gets env :ns :name)
        :use-macros
        sym))))
(defn confirm-var-exists
  ([env prefix suffix]
    (let [warn (confirm-var-exist-warning env prefix suffix)]
      (confirm-var-exists env prefix suffix warn)))
  ([env prefix suffix missing-fn]
    (let [sufstr (str suffix)
          suffix-str (if (and
                           (not= ".." sufstr)
                           (re-find #"\." sufstr))
                       (first (string/split sufstr #"\."))
                       suffix)
          suffix (symbol suffix-str)]
      (when (and
              (not (implicit-import? env prefix suffix))
              (not (loaded-js-ns? env prefix))
              (not
                (and
                  (= (quote cljs.core) prefix)
                  (= (quote unquote) suffix)))
              (nil?
                (gets
                  (clojure.core/deref env/*compiler*)
                  :cljs.analyzer/namespaces
                  prefix
                  :defs
                  suffix))
              (not (js-module-exists? prefix)))
        (missing-fn env prefix suffix)))))
(defn analyze* [env form name opts]
  (let [passes *passes*
        passes (if (nil? passes) default-passes passes)
        form (if (instance? LazySeq form) (if (seq form) form ()) form)
        ast (analyze-form env form name opts)]
    (reduce (fn [ast pass] (pass env ast opts)) ast passes)))
(defn- earmuffed? [sym]
  (let [s (name sym)]
    (and
      (> (count s) 2)
      (string/starts-with? s "*")
      (string/ends-with? s "*"))))
(defn- record-with-field? [tag field]
  (and (record-tag? tag) (contains? (record-basis tag) field)))
(defn- classify-dot-form [[target member args]]
  [(cond
     (nil? target) :cljs.analyzer/error
     :default :cljs.analyzer/expr)
   (cond
     (property-symbol? member) :cljs.analyzer/property
     (symbol? member) :cljs.analyzer/symbol
     (seq? member) :cljs.analyzer/list
     :default :cljs.analyzer/error)
   (cond (nil? args) () :default :cljs.analyzer/expr)])
(defn resolve-existing-var
  "Given env, an analysis environment, and sym, a symbol, resolve an existing var.\n   Emits a warning if no such var exists."
  [env sym]
  (if-not (-> sym meta :cljs.analyzer/no-resolve)
    (resolve-var env sym confirm-var-exists)
    (resolve-var env sym)))
(defn js-tag
  ([pre] (js-tag pre :tag))
  ([pre tag-type] (js-tag pre tag-type (get-externs)))
  ([pre tag-type externs] (js-tag pre tag-type externs externs))
  ([pre tag-type externs top]
    (when-let [[p externs' :as me] (find externs (first pre))]
      (let [tag (-> p meta tag-type)]
        (if (= (count pre) 1)
          (when tag (symbol "js" (str (alias->type tag tag))))
          (or
            (js-tag (next pre) tag-type externs' top)
            (js-tag
              (into (quote [prototype]) (next pre))
              tag-type
              (get top tag)
              top)))))))
(defn get-namespace
  ([key] (get-namespace env/*compiler* key))
  ([cenv key]
    (if-some
      [ns
       (get-in
         (clojure.core/deref cenv)
         [:cljs.analyzer/namespaces key])]
      ns
      (when (= (quote cljs.user) key) {:name (quote cljs.user)}))))
(defn- simple-predicate-induced-tag
  "Look for a predicate-induced tag when the test expression is a simple\n   application of a predicate to a local, as in (string? x)."
  [env test]
  (when (and (list? test) (== 2 (count test)) (every? symbol? test))
    (let [analyzed-fn (no-warn
                        (analyze
                          (assoc env :context :expr)
                          (first test)))]
      (when (= :var (:op analyzed-fn))
        (when-let [tag (predicate->tag (:name analyzed-fn))]
          (let [sym (last test)]
            (when (and
                    (nil? (namespace sym))
                    (get-in env [:locals sym]))
              [sym tag])))))))
(defn analyze-js-value [env form]
  (let [val (.-val form) expr-env (assoc env :context :expr)]
    (if (map? val)
      (let [keys (vec (keys val))
            vals (disallowing-recur
                   (mapv
                     (fn* [p1__4265#] (analyze expr-env p1__4265#))
                     (vals val)))]
        {:op :js-object 
         :env env 
         :form form 
         :keys keys 
         :vals vals 
         :children [:vals] 
         :tag (quote object)})
      (let [items (disallowing-recur
                    (mapv
                      (fn* [p1__4266#] (analyze expr-env p1__4266#))
                      val))]
        {:op :js-array 
         :env env 
         :form form 
         :items items 
         :children [:items] 
         :tag (quote array)}))))
(defn resolve-invokeable-ns [ns current-ns env]
  (let [ns (resolve-ns-alias env ns) module-type (ns->module-type ns)]
    (case
      module-type
      :js
      {:name
       (symbol
         (or
           (gets
             (clojure.core/deref env/*compiler*)
             :js-module-index
             ns
             :name)
           (resolve-ns-alias env ns))) 
       :op :js-var 
       :ns (quote js)}
      :node
      {:name
       (symbol
         (str current-ns)
         (munge-node-lib (resolve-ns-alias env ns))) 
       :op :js-var 
       :ns current-ns}
      :global
      {:name
       (symbol
         (str current-ns)
         (munge-global-export (resolve-ns-alias env ns))) 
       :op :js-var 
       :ns current-ns})))
(defn inferred-use-macros [use-macros env]
  (let [cenv (clojure.core/deref env/*compiler*)]
    (into
      {}
      (filter
        (fn [[sym lib]] (not (missing-use-macro? lib sym)))
        use-macros))))
(defn- invalid-arity? [argc method-params variadic max-fixed-arity]
  (and
    (not (valid-arity? argc method-params))
    (or (not variadic) (and variadic (< argc max-fixed-arity)))))
(clojure.core/defn wrapping-errors
  ([&form &env env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote try))
        body
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote catch))
              (clojure.core/list (quote java.lang.Throwable))
              (clojure.core/list (quote err__2944__auto__))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/cond))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote cljs.analyzer/has-error-data?))
                          (clojure.core/list
                            (quote err__2944__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote throw))
                          (clojure.core/list
                            (quote err__2944__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote cljs.analyzer/analysis-error?))
                          (clojure.core/list
                            (quote err__2944__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote throw))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/ex-info))
                                (clojure.core/list (quote nil))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.analyzer/error-data))
                                      (clojure.core/list env)
                                      (clojure.core/list
                                        :compilation))))
                                (clojure.core/list
                                  (quote err__2944__auto__))))))))
                    (clojure.core/list :else)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote throw))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/ex-info))
                                (clojure.core/list (quote nil))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.analyzer/error-data))
                                      (clojure.core/list env)
                                      (clojure.core/list
                                        :compilation))))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote cljs.analyzer/error))
                                      (clojure.core/list env)
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote .getMessage))
                                            (clojure.core/list
                                              (quote
                                                err__2944__auto__)))))
                                      (clojure.core/list
                                        (quote
                                          err__2944__auto__)))))))))))))))))))))
(defmethod
  error-message
  :js-shadowed-by-local
  [warning-type {:keys [name]}]
  (str name " is shadowed by a local"))
(defmethod
  resolve*
  :goog-module
  [env sym full-ns current-ns]
  {:name
   (symbol
     (str current-ns)
     (str (munge-goog-module-lib full-ns) "." (name sym))) 
   :ns current-ns 
   :op :var})
(defn check-rename-macros-inferring-missing [{:keys [name renames] 
                                              :as ast}
                                             env]
  (let [missing-renames (when (and *analyze-deps* (seq renames))
                          (missing-renames renames env))
        maybe-macros (apply dissoc renames (keys missing-renames))
        missing-rename-macros (inferred-rename-macros
                                missing-renames
                                env)
        remove-missing-renames (fn*
                                 [p1__3710#]
                                 (apply
                                   dissoc
                                   p1__3710#
                                   (keys missing-renames)))
        ast' (-> ast
              (update-in
                [:rename-macros]
                (fn*
                  [p1__3711#]
                  (-> p1__3711#
                   (merge missing-rename-macros)
                   (merge (inferred-rename-macros maybe-macros env)))))
              (update-in [:renames] remove-missing-renames))]
    (swap!
      env/*compiler*
      (fn*
        [p1__3712#]
        (-> p1__3712#
         (update-in
           [:cljs.analyzer/namespaces name :rename-macros]
           merge
           (:rename-macros ast'))
         (update-in
           [:cljs.analyzer/namespaces name :renames]
           remove-missing-renames))))
    ast'))
(defn inferred-rename-macros [rename-macros env]
  (into
    {}
    (filter
      (fn [[_ qualified-sym]]
        (not (missing-rename-macro? qualified-sym)))
      rename-macros)))
(defn get-line [x env] (or (-> x meta :line) (:line env)))
(defn desugar-dotted-expr [{:keys [op]  :as expr}]
  (case
    op
    (:var :local)
    (if (dotted-symbol? (symbol (name (:name expr))))
      (let [s (name (:name expr))
            idx (.lastIndexOf s ".")
            _ (assert (not= (inc idx) (count s)))
            prefix (with-meta
                     (symbol (namespace (:name expr)) (subs s 0 idx))
                     (meta (:form expr)))
            field (symbol (subs s (inc idx)))]
        (assert (not (:const-expr expr)))
        {:op :host-field 
         :env (:env expr) 
         :form (list (quote .) prefix field) 
         :target
         (desugar-dotted-expr
           (-> expr
            (assoc :name prefix :form prefix)
            (dissoc :tag)
            (assoc-in [:info :name] prefix)
            (assoc-in [:env :context] :expr))) 
         :field field 
         :tag (:tag expr) 
         :children [:target]})
      expr)
    expr))
(defmethod
  resolve*
  :default
  [env sym full-ns current-ns]
  (let [sym-ast (gets
                  (clojure.core/deref env/*compiler*)
                  :cljs.analyzer/namespaces
                  full-ns
                  :defs
                  (symbol (name sym)))
        sym-name (symbol (str full-ns) (str (name sym)))]
    (when (and
            (not= current-ns full-ns)
            (:private sym-ast)
            (not *private-var-access-nowarn*)
            (not (contains? private-var-access-exceptions sym-name)))
      (warning :private-var-access env {:sym sym-name}))
    (merge sym-ast {:name sym-name  :op :var  :ns full-ns})))
(defn analyze-map [env form]
  (let [expr-env (assoc env :context :expr)
        ks (disallowing-recur
             (mapv
               (fn* [p1__4236#] (analyze expr-env p1__4236#))
               (keys form)))
        vs (disallowing-recur
             (mapv
               (fn* [p1__4237#] (analyze expr-env p1__4237#))
               (vals form)))]
    (analyze-wrap-meta
      {:op :map 
       :env env 
       :form form 
       :keys ks 
       :vals vs 
       :children [:keys :vals] 
       :tag (quote cljs.core/IMap)})))
(defn normalize-js-tag [x]
  (if-not (= (quote js) x)
    (with-meta
      (quote js)
      {:prefix
       (conj
         (->> (string/split (name x) #"\.") (map symbol) vec)
         (quote prototype))})
    x))
(defn dep-has-global-exports? [module]
  (let [[module _] (lib&sublib module)
        global-exports (get-in
                         (clojure.core/deref env/*compiler*)
                         [:js-dependency-index
                          (str module)
                          :global-exports])]
    (or
      (contains? global-exports (symbol module))
      (contains? global-exports (name module)))))
(defn- replay-accumulated-warnings [warn-acc]
  (run!
    (fn* [p1__2935#] (apply warning p1__2935#))
    (clojure.core/deref warn-acc)))
(clojure.core/defn disallowing-recur
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list
                  (quote cljs.analyzer/*recur-frames*))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote clojure.core/cons))
                      (clojure.core/list (quote nil))
                      (clojure.core/list
                        (quote cljs.analyzer/*recur-frames*)))))))))
        body))))
(clojure.core/defn no-warn
  ([&form &env & body]
    (let [no-warnings (zipmap (keys *cljs-warnings*) (repeat false))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/binding))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote cljs.analyzer/*cljs-warnings*))
                  (clojure.core/list no-warnings)))))
          body)))))
(defn- internal-js-module-exists? [js-module-index module]
  (contains?
    (into #{} (mapcat (fn [[k v]] [k (:name v)])) js-module-index)
    (str module)))
(defn analyze-const [env form]
  (let [{:keys [tag]} (analyze (assoc env :quoted? true) form)]
    {:op :const 
     :env env 
     :literal? true 
     :val form 
     :tag tag 
     :form form}))
(defn- source-info->error-data [{:keys [file line column]}]
  {:clojure.error/sourcefile:clojure.error/lineline :clojure.error/columncolumn})
(clojure.core/defn allowing-redef
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.analyzer/*allow-redef*))
                (clojure.core/list (quote true))))))
        body))))
(defmethod
  error-message
  :undeclared-var
  [warning-type info]
  (str
    (if (:macro-present? info)
      "Can't take value of macro "
      "Use of undeclared Var ")
    (:prefix info)
    "/"
    (:suffix info)))
(defn parse-ns-error-msg [spec msg]
  (str msg "; offending spec: " (pr-str spec)))
(defn resolve-var
  "Resolve a var. Accepts a side-effecting confirm fn for producing\n   warnings about unresolved vars."
  ([env sym] (resolve-var env sym nil))
  ([env sym confirm] (resolve-var env sym confirm true))
  ([env sym confirm default?]
    (let [locals (:locals env)]
      (if (= "js" (namespace sym))
        (let [symn (-> sym name symbol)
              shadowed-by-local (handle-symbol-local
                                  symn
                                  (get locals symn))]
          (cond
            (some? shadowed-by-local) (do
                                        (warning
                                          :js-shadowed-by-local
                                          env
                                          {:name sym})
                                        (assoc
                                          shadowed-by-local
                                          :op
                                          :local))
            :else (let [pre (->>
                              (string/split (name sym) #"\.")
                              (map symbol)
                              vec)]
                    (when (and
                            (not (has-extern? pre))
                            (not
                              (-> sym meta :cljs.analyzer/no-resolve)))
                      (swap!
                        env/*compiler*
                        update-in
                        (into
                          [:cljs.analyzer/namespaces
                           (-> env :ns :name)
                           :externs]
                          pre)
                        merge
                        {}))
                    (merge
                      {:name sym 
                       :op :js-var 
                       :ns (quote js) 
                       :tag
                       (with-meta
                         (or (js-tag pre) (:tag (meta sym)) (quote js))
                         {:prefix pre})}
                      (when-let [ret-tag (js-tag pre :ret-tag)]
                        {:js-fn-var true  :ret-tag ret-tag})))))
        (let [s (str sym)
              lb (handle-symbol-local sym (get locals sym))
              current-ns (-> env :ns :name)]
          (cond
            (some? lb) (assoc lb :op :local)
            (some? (namespace sym)) (let 
                                      [ns (namespace sym)
                                       ns
                                       (if
                                         (= "clojure.core" ns)
                                         "cljs.core"
                                         ns)
                                       full-ns
                                       (resolve-ns-alias
                                         env
                                         ns
                                         (or
                                           (and
                                             (js-module-exists? ns)
                                             (gets
                                               (clojure.core/deref
                                                 env/*compiler*)
                                               :js-module-index
                                               ns
                                               :name))
                                           (symbol ns)))]
                                      (when
                                        (some? confirm)
                                        (when
                                          (not= current-ns full-ns)
                                          (confirm-ns env full-ns))
                                        (confirm
                                          env
                                          full-ns
                                          (symbol (name sym))))
                                      (resolve*
                                        env
                                        sym
                                        full-ns
                                        current-ns))
            (dotted-symbol? sym) (let 
                                   [idx (.indexOf s ".")
                                    prefix (symbol (subs s 0 idx))
                                    suffix (subs s (inc idx))]
                                   (if-let 
                                     [resolved
                                      (resolve-var
                                        env
                                        prefix
                                        nil
                                        false)]
                                     (update
                                       resolved
                                       :name
                                       (fn*
                                         [p1__3083#]
                                         (symbol
                                           (str
                                             p1__3083#
                                             "."
                                             suffix))))
                                     (let 
                                       [s
                                        (str
                                          (cond->>
                                            s
                                            (goog-module-dep? sym)
                                            (resolve-import env)))
                                        idx (.lastIndexOf (str s) ".")
                                        pre (subs s 0 idx)
                                        suf (subs s (inc idx))]
                                       {:op :var 
                                        :name (symbol pre suf) 
                                        :ns (symbol pre)})))
            (some?
              (gets
                (clojure.core/deref env/*compiler*)
                :cljs.analyzer/namespaces
                current-ns
                :uses
                sym)) (let [full-ns (gets
                                      (clojure.core/deref
                                        env/*compiler*)
                                      :cljs.analyzer/namespaces
                                      current-ns
                                      :uses
                                      sym)]
                        (resolve* env sym full-ns current-ns))
            (some?
              (gets
                (clojure.core/deref env/*compiler*)
                :cljs.analyzer/namespaces
                current-ns
                :renames
                sym)) (let [qualified-symbol (gets
                                               (clojure.core/deref
                                                 env/*compiler*)
                                               :cljs.analyzer/namespaces
                                               current-ns
                                               :renames
                                               sym)
                            full-ns (symbol
                                      (namespace qualified-symbol))
                            sym (symbol (name qualified-symbol))]
                        (resolve* env sym full-ns current-ns))
            (some?
              (gets
                (clojure.core/deref env/*compiler*)
                :cljs.analyzer/namespaces
                current-ns
                :imports
                sym)) (recur
                        env
                        (gets
                          (clojure.core/deref env/*compiler*)
                          :cljs.analyzer/namespaces
                          current-ns
                          :imports
                          sym)
                        confirm
                        default?)
            (some?
              (gets
                (clojure.core/deref env/*compiler*)
                :cljs.analyzer/namespaces
                current-ns
                :defs
                sym)) (do
                        (when (some? confirm)
                          (confirm env current-ns sym))
                        (merge
                          (gets
                            (clojure.core/deref env/*compiler*)
                            :cljs.analyzer/namespaces
                            current-ns
                            :defs
                            sym)
                          {:name (symbol (str current-ns) (str sym)) 
                           :op :var 
                           :ns current-ns}))
            (core-name? env sym) (let 
                                   [sym
                                    (resolve-alias
                                      (quote cljs.core)
                                      sym)]
                                   (when
                                     (some? confirm)
                                     (confirm
                                       env
                                       (quote cljs.core)
                                       sym))
                                   (merge
                                     (gets
                                       (clojure.core/deref
                                         env/*compiler*)
                                       :cljs.analyzer/namespaces
                                       (quote cljs.core)
                                       :defs
                                       sym)
                                     {:name
                                      (symbol "cljs.core" (str sym)) 
                                      :op :var 
                                      :ns (quote cljs.core)}))
            (invokeable-ns? s env) (resolve-invokeable-ns
                                     s
                                     current-ns
                                     env)
            :else (when default?
                    (when (some? confirm) (confirm env current-ns sym))
                    (merge
                      (gets
                        (clojure.core/deref env/*compiler*)
                        :cljs.analyzer/namespaces
                        current-ns
                        :defs
                        sym)
                      {:name (symbol (str current-ns) (str sym)) 
                       :op :var 
                       :ns current-ns}))))))))
(defn analyze-let-body* [env context exprs]
  (analyze
    (assoc env :context (if (= :expr context) :return context))
    (clojure.core/seq
      (clojure.core/concat (clojure.core/list (quote do)) exprs))))
(defn- hex-format [s pad]
  (str "_u" (format (str "%0" pad "x") (int (first s))) "_"))
(defn elide-irrelevant-meta [m]
  (-> m elide-reader-meta elide-analyzer-meta))
(defn- truth-induced-tag
  "Refine a tag to exclude clj-nil if the test is a local."
  [env test]
  (when (and
          (symbol? test)
          (nil? (namespace test))
          (get-in env [:locals test]))
    (let [analyzed-symbol (no-warn
                            (analyze (assoc env :context :expr) test))]
      (when-let [tag (:tag analyzed-symbol)]
        (when (and (set? tag) (contains? tag (quote clj-nil)))
          [test (canonicalize-type (disj tag (quote clj-nil)))])))))
(defmethod
  parse
  (quote .)
  [_ env [_ target & [field & member+] :as form] _ _]
  (disallowing-recur (analyze-dot env target field member+ form)))
(defn invokeable-ns?
  "Returns true if ns is a required namespace and a JavaScript module that\n   might be invokeable as a function."
  [ns env]
  (let [ns (resolve-ns-alias env ns)]
    (and
      (required? ns env)
      (or
        (js-module-exists? ns)
        (node-module-dep? ns)
        (dep-has-global-exports? ns)))))
(defn gen-user-ns [src]
  (if (sequential? src)
    (symbol
      (str "cljs.user.source$form$" (util/content-sha (pr-str src) 7)))
    (let [full-name (str src)
          name (.substring
                 full-name
                 (inc (.lastIndexOf full-name "/"))
                 (.lastIndexOf full-name "."))]
      (symbol (str "cljs.user." name (util/content-sha full-name 7))))))
(defmethod
  error-message
  :multiple-variadic-overloads
  [warning-type info]
  (str (:name info) ": Can't have more than 1 variadic overload"))
(defn canonicalize-import-specs [specs]
  (letfn
    [(canonicalize
       [quoted-spec-or-kw]
       (if (keyword? quoted-spec-or-kw)
         quoted-spec-or-kw
         (second quoted-spec-or-kw)))]
    (map canonicalize specs)))
(defn- record-tag? [tag]
  (boolean
    (and
      (symbol? tag)
      (some? (namespace tag))
      (get-in
        (clojure.core/deref env/*compiler*)
        [:cljs.analyzer/namespaces
         (symbol (namespace tag))
         :defs
         (symbol (name tag))
         :record]))))
(defn elide-analyzer-meta [m] (dissoc m :cljs.analyzer/analyzed))
(defn infer-if [env ast]
  (let [{:keys [op form]} (unwrap-quote (:test ast))
        then-tag (infer-tag env (:then ast))]
    (if (and (= op :const) (not (nil? form)) (not (false? form)))
      then-tag
      (let [else-tag (infer-tag env (:else ast))]
        (cond
          (or (= then-tag else-tag) (= else-tag impl/IGNORE_SYM)) then-tag
          (= then-tag impl/IGNORE_SYM) else-tag
          (and
            (or
              (some? (get impl/NOT_NATIVE then-tag))
              (type? env then-tag))
            (or
              (some? (get impl/NOT_NATIVE else-tag))
              (type? env else-tag))) (quote clj)
          :else (if (and
                      (some? (get impl/BOOLEAN_OR_SEQ then-tag))
                      (some? (get impl/BOOLEAN_OR_SEQ else-tag)))
                  (quote seq)
                  (let [then-tag (if
                                   (set? then-tag)
                                   then-tag
                                   #{then-tag})
                        else-tag (if
                                   (set? else-tag)
                                   else-tag
                                   #{else-tag})]
                    (into then-tag else-tag))))))))
(defn analyze-wrap-meta [expr]
  (let [form (:form expr) m (elide-irrelevant-meta (meta form))]
    (if (some? (seq m))
      (let [env (:env expr)
            expr (assoc-in expr [:env :context] :expr)
            meta-expr (analyze-map (:env expr) m)]
        {:op :with-meta 
         :env env 
         :form form 
         :meta meta-expr 
         :expr expr 
         :children [:meta :expr]})
      expr)))
(defn node-like?
  ([] (node-like? (compiler-options)))
  ([opts] (and (= :nodejs (:target opts)) (false? (:nodejs-rt opts)))))
(defn analyzed?
  "Returns boolean if the form has already been marked as analyzed."
  [x]
  (boolean
    (cond
      (unsorted-map? x) (:cljs.analyzer/analyzed x)
      :else (:cljs.analyzer/analyzed (meta x)))))
(defn analyze-fn-methods-pass2* [menv locals type meths]
  (mapv
    (fn*
      [p1__3402#]
      (analyze-fn-method menv locals p1__3402# type true))
    meths))
(defn analysis-error? [ex] (= :cljs/analysis-error (:tag (ex-data ex))))
(defmethod
  error-message
  :fn-arity
  [warning-type info]
  (str
    "Wrong number of args ("
    (:argc info)
    ") passed to "
    (or (:ctor info) (:name info))))
(defn get-col [x env] (or (-> x meta :column) (:column env)))
(defn core-name?
  "Is sym visible from core in the current compilation namespace?"
  [env sym]
  (and
    (or
      (some?
        (gets
          (clojure.core/deref env/*compiler*)
          :cljs.analyzer/namespaces
          (quote cljs.core)
          :defs
          sym))
      (if-some
        [mac (get-expander sym env)]
        (let [ns (-> mac meta :ns)]
          (= (.getName ns) (quote cljs.core)))
        false))
    (not (contains? (-> env :ns :excludes) sym))))
(defn js-var? [ast] (= :js-var (:op ast)))
(defmethod
  parse
  (quote deftype*)
  [_ env form _ _]
  (parse-type :deftype env form))
(defn analyze-seq* [op env form name opts]
  (if (contains? specials op)
    (parse op env form name opts)
    (parse-invoke env form)))
(defn required? [ns env]
  (or
    (contains? (set (vals (gets env :ns :requires))) ns)
    (contains? (set (vals (gets env :ns :uses))) ns)))
(defn js-star-seg [s]
  (let [idx (.indexOf s "~{")]
    (if (== -1 idx)
      (list s)
      (let [end (.indexOf s "}" idx)]
        (lazy-seq
          (cons (subs s 0 idx) (js-star-seg (subs s (inc end)))))))))
(defn- type-check-induced-tag
  "Look for a type-check-induced tag when the test expression is the use of\n  instance? on a local, as in (instance? UUID x) or implements? on a local, as\n  in (implements? ICounted x)."
  [env test]
  (when (and
          (list? test)
          (== 3 (count test))
          (every? symbol? test)
          (not (contains? specials (first test))))
    (let [analyzed-fn (no-warn
                        (analyze
                          (assoc env :context :expr)
                          (first test)))]
      (when (= :var (:op analyzed-fn))
        (when ((quote #{cljs.core/implements? cljs.core/instance?})
                (:name analyzed-fn))
          (let [analyzed-type (no-warn
                                (analyze
                                  (assoc env :context :expr)
                                  (second test)))
                tag (:name analyzed-type)
                sym (last test)]
            (when (and
                    (= :var (:op analyzed-type))
                    (nil? (namespace sym))
                    (get-in env [:locals sym]))
              [sym tag])))))))
(defn build-affecting-options [opts]
  (select-keys
    opts
    [:static-fns
     :fn-invoke-direct
     :optimize-constants
     :elide-asserts
     :target
     :nodejs-rt
     :cache-key
     :checked-arrays
     :language-out
     :optimizations]))
(defn var-ast [env sym]
  (binding [*private-var-access-nowarn* true]
    (let [env (dissoc env :locals)
          var (resolve-var env sym (confirm-var-exists-throw))
          expr-env (assoc env :context :expr)]
      (when-some
        [var-ns (:ns var)]
        {:var (analyze expr-env sym) 
         :sym
         (analyze
           expr-env
           (clojure.core/seq
             (clojure.core/concat
               (clojure.core/list (quote quote))
               (clojure.core/list
                 (symbol (name var-ns) (name (:name var))))))) 
         :meta (var-meta var expr-env)}))))
(defn valid-proto [x] (when (symbol? x) x))
(defn replace-env-pass [new-env]
  (fn [env ast opts] (assoc ast :env new-env)))
(defn ->type-set
  "Ensures that a type tag is a set."
  [t]
  (if (set? t) t #{t}))
(defn missing-use? [lib sym cenv]
  (let [js-lib (get-in cenv [:js-dependency-index (name lib)])]
    (and
      (=
        (get-in
          cenv
          [:cljs.analyzer/namespaces lib :defs sym]
          :cljs.analyzer/not-found)
        :cljs.analyzer/not-found)
      (not (= (get js-lib :group) :goog))
      (not (get js-lib :closure-lib))
      (not (node-module-dep? lib))
      (not (dep-has-global-exports? lib)))))
(defmethod
  resolve*
  :global
  [env sym full-ns current-ns]
  (let [pre (extern-pre sym current-ns)]
    {:ns current-ns 
     :name
     (symbol
       (str current-ns)
       (str (munge-global-export full-ns) "." (name sym))) 
     :op :js-var 
     :tag (with-meta (quote js) {:prefix pre}) 
     :foreign true}))
(defn handle-symbol-local [sym lb] (if (symbol? lb) {:name sym} lb))
(defn excluded? [env sym]
  (or
    (some? (gets env :ns :excludes sym))
    (some?
      (gets
        (clojure.core/deref env/*compiler*)
        :cljs.analyzer/namespaces
        (gets env :ns :name)
        :excludes
        sym))))
(defn get-let-tag [name init-expr]
  (if-some
    [tag (-> name meta :tag)]
    tag
    (if-some [tag (-> init-expr :tag)] tag (-> init-expr :info :tag))))
(defmethod
  error-message
  :private-var-access
  [warning-type info]
  (str "var: " (:sym info) " is not public"))
(defn- var->sym [var] (symbol (str (.-ns var)) (str (.-sym var))))
(defn missing-use-macros [use-macros env]
  (let [cenv (clojure.core/deref env/*compiler*)]
    (into
      {}
      (filter
        (fn [[sym lib]] (missing-use-macro? lib sym))
        use-macros))))
(defn numeric-type? [t]
  (cond
    (nil? t) true
    (= (quote clj-nil) t) true
    (js-tag? t) true
    :else (if (and (symbol? t) (some? (get NUMERIC_SET t)))
            true
            (when (set? t)
              (or
                (contains? t (quote number))
                (contains? t (quote long))
                (contains? t (quote double))
                (contains? t (quote any))
                (contains? t (quote js)))))))
(defmethod
  parse
  (quote defrecord*)
  [_ env form _ _]
  (parse-type :defrecord env form))
(defmethod
  parse
  (quote loop*)
  [op encl-env form _ _]
  (analyze-let encl-env form true nil))
(defn gets
  ([m k0 k1]
    (let [m (get m k0 SENTINEL)]
      (when-not (identical? m SENTINEL) (get m k1))))
  ([m k0 k1 k2]
    (let [m (get m k0 SENTINEL)]
      (when-not (identical? m SENTINEL)
        (let [m (get m k1 SENTINEL)]
          (when-not (identical? m SENTINEL) (get m k2))))))
  ([m k0 k1 k2 k3]
    (let [m (get m k0 SENTINEL)]
      (when-not (identical? m SENTINEL)
        (let [m (get m k1 SENTINEL)]
          (when-not (identical? m SENTINEL)
            (let [m (get m k2 SENTINEL)]
              (when-not (identical? m SENTINEL) (get m k3)))))))))
(defn- all-values? [exprs]
  (every?
    (fn*
      [p1__4154#]
      (or
        (nil? p1__4154#)
        (symbol? p1__4154#)
        (string? p1__4154#)
        (number? p1__4154#)
        (true? p1__4154#)
        (false? p1__4154#)))
    exprs))
(defn- cache-analysis-ext
  ([]
    (cache-analysis-ext
      (get-in
        (clojure.core/deref env/*compiler*)
        [:options :cache-analysis-format]
        :transit)))
  ([format]
    (if (and (= format :transit) (clojure.core/deref transit))
      "json"
      "edn")))
(defn error
  ([env msg] (error env msg nil))
  ([env msg cause]
    (ex-info
      (message env msg)
      (assoc (source-info env) :tag :cljs/analysis-error)
      cause)))
(defmethod
  error-message
  :single-segment-namespace
  [warning-type info]
  (str (:name info) " is a single segment namespace"))
(defn check-use-macros-inferring-missing [{:keys
                                           [name uses use-macros] 
                                           :as ast}
                                          env]
  (let [missing-uses (when (and *analyze-deps* (seq uses))
                       (missing-uses uses env))
        maybe-macros (apply dissoc uses (keys missing-uses))
        remove-missing-uses (fn*
                              [p1__3697#]
                              (apply
                                dissoc
                                p1__3697#
                                (keys missing-uses)))
        ast' (-> ast
              (update-in
                [:use-macros]
                (fn*
                  [p1__3698#]
                  (-> p1__3698#
                   (merge
                     (check-use-macros use-macros missing-uses env))
                   (merge (inferred-use-macros maybe-macros env)))))
              (update-in [:uses] remove-missing-uses))]
    (swap!
      env/*compiler*
      (fn*
        [p1__3699#]
        (-> p1__3699#
         (update-in
           [:cljs.analyzer/namespaces name :use-macros]
           merge
           (:use-macros ast'))
         (update-in
           [:cljs.analyzer/namespaces name :uses]
           remove-missing-uses))))
    ast'))
(defn analyze-dot [env target field member+ form]
  (let [v [target field member+]
        {:keys [dot-action target method field args]} (build-dot-form
                                                        v)
        enve (assoc env :context :expr)
        targetexpr (analyze enve target)
        form-meta (meta form)
        target-tag (:tag targetexpr)
        prop (or field method)
        tag (or
              (:tag form-meta)
              (and
                (js-tag? target-tag)
                (vary-meta
                  (normalize-js-tag target-tag)
                  update-in
                  [:prefix]
                  (fnil conj (quote [Object]))
                  prop))
              nil)]
    (when (and
            (not= (quote constructor) prop)
            (not (string/starts-with? (str prop) "cljs$"))
            (not (-> prop meta :protocol-prop)))
      (when (= (quote Object) (first (-> tag meta :prefix)))
        (warning
          :infer-warning
          env
          {:warn-type :object  :form form  :property prop}))
      (when (not= (quote js) target-tag)
        (when (or (nil? target-tag) ((quote #{any}) target-tag))
          (warning
            :infer-warning
            env
            {:warn-type :target  :form form  :property prop}))
        (let [[pre' pre] ((juxt butlast identity)
                           (-> tag meta :prefix))]
          (when (and (has-extern? pre') (not (has-extern? pre)))
            (warning
              :infer-warning
              env
              {:warn-type :property 
               :form form 
               :type
               (symbol
                 "js"
                 (string/join
                   "."
                   (cond->
                     pre'
                     (= (quote prototype) (last pre'))
                     butlast))) 
               :property prop})))))
    (when (js-tag? tag)
      (let [pre (-> tag meta :prefix)]
        (when-not (has-extern? pre)
          (swap!
            env/*compiler*
            update-in
            (into
              [:cljs.analyzer/namespaces (-> env :ns :name) :externs]
              pre)
            merge
            {}))))
    (case
      dot-action
      :cljs.analyzer/access
      (let [children [:target]]
        {:op :host-field 
         :env env 
         :form form 
         :target targetexpr 
         :field field 
         :children children 
         :tag
         (if (js-tag? tag)
           (or (js-tag (-> tag meta :prefix) :tag) tag)
           tag)})
      :cljs.analyzer/call
      (let [argexprs (mapv
                       (fn* [p1__4075#] (analyze enve p1__4075#))
                       args)
            children [:target :args]]
        {:op :host-call 
         :env env 
         :form form 
         :target targetexpr 
         :method method 
         :args argexprs 
         :children children 
         :tag
         (if (js-tag? tag)
           (or (js-tag (-> tag meta :prefix) :ret-tag) (quote js))
           tag)}))))
(defn has-extern?*
  ([pre externs]
    (let [pre (if-some
                [me
                 (find
                   (get-in externs (quote [Window prototype]))
                   (first pre))]
                (if-some
                  [tag (-> me first meta :tag)]
                  (into [tag (quote prototype)] (next pre))
                  pre)
                pre)]
      (has-extern?* pre externs externs)))
  ([pre externs top]
    (cond
      (empty? pre) true
      :else (let [x (first pre) me (find externs x)]
              (cond
                (not me) false
                :else (let [[x' externs'] me xmeta (meta x')]
                        (if (and
                              (= (quote Function) (:tag xmeta))
                              (:ctor xmeta))
                          (or
                            (has-extern?*
                              (into (quote [prototype]) (next pre))
                              externs'
                              top)
                            (has-extern?* (next pre) externs' top))
                          (recur (next pre) externs' top))))))))
(defn basic-validate-ns-spec [env macros? spec]
  (when-not (or (symbol? spec) (string? spec) (sequential? spec))
    (throw
      (error
        env
        (parse-ns-error-msg
          spec
          "Only [lib.ns & options] and lib.ns specs supported in :require / :require-macros"))))
  (when (sequential? spec)
    (when-not (or (symbol? (first spec)) (string? (first spec)))
      (throw
        (error
          env
          (parse-ns-error-msg
            spec
            "Library name must be specified as a symbol in :require / :require-macros"))))
    (when-not (odd? (count spec))
      (throw
        (error
          env
          (parse-ns-error-msg
            spec
            "Only :as alias, :refer (names) and :rename {from to} options supported in :require"))))
    (when-not (every?
                #{:as :rename :refer}
                (map first (partition 2 (next spec))))
      (throw
        (error
          env
          (parse-ns-error-msg
            spec
            "Only :as, :refer and :rename options supported in :require / :require-macros"))))
    (when-not (let [fs (frequencies (next spec))]
                (and (<= (fs :as 0) 1) (<= (fs :refer 0) 1)))
      (throw
        (error
          env
          (parse-ns-error-msg
            spec
            "Each of :as and :refer options may only be specified once in :require / :require-macros"))))))
(defn analyze-let [encl-env
                   [_ bindings & exprs :as form]
                   is-loop
                   widened-tags]
  (when-not (and (vector? bindings) (even? (count bindings)))
    (throw
      (error
        encl-env
        "bindings must be vector of even number of elements")))
  (let [context (:context encl-env)
        op (if (true? is-loop) :loop :let)
        bindings (if widened-tags
                   (vec
                     (mapcat
                       (fn [[name init] widened-tag] [(vary-meta
                                                        name
                                                        assoc
                                                        :tag
                                                        widened-tag)
                                                      init])
                       (partition 2 bindings)
                       widened-tags))
                   bindings)
        [bes env] (-> encl-env
                   (cond-> (true? is-loop) (assoc :in-loop true))
                   (analyze-let-bindings bindings op))
        recur-frame (when (true? is-loop)
                      {:params bes 
                       :flag (atom nil) 
                       :tags (atom (mapv :tag bes))})
        recur-frames (if recur-frame
                       (cons recur-frame *recur-frames*)
                       *recur-frames*)
        loop-lets (cond
                    (true? is-loop) *loop-lets*
                    (some? *loop-lets*) (cons
                                          {:params bes}
                                          *loop-lets*))
        warn-acc (when (and is-loop (not widened-tags)) (atom []))
        expr (if warn-acc
               (with-warning-handlers
                 [(accumulating-warning-handler warn-acc)]
                 (analyze-let-body
                   env
                   context
                   exprs
                   recur-frames
                   loop-lets))
               (analyze-let-body
                 env
                 context
                 exprs
                 recur-frames
                 loop-lets))
        children [:bindings :body]
        nil->any (fnil identity (quote any))]
    (if (and
          is-loop
          (not widened-tags)
          (not=
            (mapv nil->any (clojure.core/deref (:tags recur-frame)))
            (mapv (comp nil->any :tag) bes)))
      (recur
        encl-env
        form
        is-loop
        (clojure.core/deref (:tags recur-frame)))
      (do
        (when warn-acc (replay-accumulated-warnings warn-acc))
        {:op op 
         :env encl-env 
         :bindings bes 
         :body (assoc expr :body? true) 
         :form form 
         :children children}))))
(defn analyze-symbol
  "Finds the var associated with sym"
  [env sym]
  (if (:quoted? env)
    (do
      (register-constant! env sym)
      (analyze-wrap-meta
        {:op :const 
         :val sym 
         :env env 
         :form sym 
         :tag (quote cljs.core/Symbol)}))
    (let [{:keys [line column]} (meta sym)
          env (if-not (nil? line) (assoc env :line line) env)
          env (if-not (nil? column) (assoc env :column column) env)
          ret {:env env  :form sym}
          lcls (:locals env)]
      (if-some
        [lb (handle-symbol-local sym (get lcls sym))]
        (merge
          (assoc ret :op :local :info lb)
          (when (map? lb)
            (select-keys lb [:name :local :arg-id :variadic? :init])))
        (let [sym-meta (meta sym)
              sym-ns (namespace sym)
              cur-ns (str (-> env :ns :name))
              info (if-not (contains? sym-meta :cljs.analyzer/analyzed)
                     (resolve-existing-var env sym)
                     (resolve-var env sym))]
          (assert (:op info) (:op info))
          (desugar-dotted-expr
            (if-not (true? (:def-var env))
              (merge
                (assoc ret :info info)
                (select-keys info [:op :name :ns :tag])
                (when-let [const-expr (:const-expr info)]
                  {:const-expr const-expr}))
              (let [info (resolve-var env sym)]
                (merge
                  (assoc ret :op :var :info info)
                  (select-keys info [:op :name :ns :tag]))))))))))
(defn macroexpand-1* [env form]
  (let [op (first form)]
    (if (contains? specials op)
      (do
        (when (= (quote ns) op)
          (do-macroexpand-check
            env
            form
            (get-expander (quote cljs.core/ns-special-form) env)))
        form)
      (if-some
        [mac-var (when (symbol? op) (get-expander op env))]
        (binding [*ns* (create-ns *cljs-ns*)]
          (do-macroexpand-check env form mac-var)
          (let [form' (try
                        (apply
                          (clojure.core/deref mac-var)
                          form
                          env
                          (rest form))
                        (catch
                          ArityException
                          e
                          (throw
                            (ArityException.
                              (- (.actual e) 2)
                              (.name e))))
                        (catch
                          Throwable
                          e
                          (throw
                            (ex-info
                              nil
                              (error-data
                                env
                                :macroexpansion
                                (var->sym mac-var))
                              e))))]
            (if (seq? form')
              (let [sym' (first form') sym (first form)]
                (if (= sym' (quote js*))
                  (let [sym (if (some? (namespace sym))
                              sym
                              (symbol "cljs.core" (str sym)))
                        js-op {:js-op sym}
                        numeric (->
                                 mac-var
                                 meta
                                 :cljs.analyzer/numeric)
                        js-op (if (true? numeric)
                                (assoc js-op :numeric true)
                                js-op)]
                    (vary-meta form' merge js-op))
                  form'))
              form')))
        (if (symbol? op)
          (let [opname (str op)]
            (cond
              (identical? \. (first opname)) (let 
                                               [[target & args]
                                                (next form)]
                                               (with-meta
                                                 (list*
                                                   (quote .)
                                                   target
                                                   (symbol
                                                     (subs opname 1))
                                                   args)
                                                 (meta form)))
              (identical? \. (last opname)) (with-meta
                                              (list*
                                                (quote new)
                                                (symbol
                                                  (subs
                                                    opname
                                                    0
                                                    (dec
                                                      (count opname))))
                                                (next form))
                                              (meta form))
              :else form))
          form)))))
(defn- check-duplicate-aliases [env old new]
  (let [ns-name (:name old)]
    (doseq [k [:requires :require-macros]]
      (let [old-aliases (get old k) new-aliases (get new k)]
        (when-some
          [alias
           (some
             (set (keys new-aliases))
             (->>
               old-aliases
               (remove
                 (fn [[k v :as entry]]
                   (or (= k v) (= entry (find new-aliases k)))))
               keys))]
          (throw
            (error
              env
              (str
                "Alias "
                alias
                " already exists in namespace "
                ns-name
                ", aliasing "
                (get old-aliases alias)))))))))
(defn desugar-ns-specs
  "Given an original set of ns specs desugar :include-macros and :refer-macros\n   usage into only primitive spec forms - :use, :require, :use-macros,\n   :require-macros. If a library includes a macro file of with the same name\n   as the namespace will also be desugared."
  [args]
  (let [{:keys [require]  :as indexed} (->>
                                         args
                                         (map
                                           (fn 
                                             [[k & specs]]
                                             [k (into [] specs)]))
                                         (into {}))
        sugar-keys #{:include-macros :refer-macros}
        remove-from-spec (fn [pred spec]
                           (if-not (and
                                     (sequential? spec)
                                     (some pred spec))
                             spec
                             (let [[l r]
                                   (split-with (complement pred) spec)]
                               (recur pred (concat l (drop 2 r))))))
        replace-refer-macros (fn [spec]
                               (if-not
                                 (sequential? spec)
                                 spec
                                 (map
                                   (fn 
                                     [x]
                                     (if (= x :refer-macros) :refer x))
                                   spec)))
        reload-spec? (fn*
                       [p1__3832#]
                       (#{:reload :reload-all} p1__3832#))
        to-macro-specs (fn [specs]
                         (->>
                           specs
                           (filter
                             (fn [x]
                               (or
                                 (and
                                   (sequential? x)
                                   (some sugar-keys x))
                                 (reload-spec? x)
                                 (macro-autoload-ns? x))))
                           (map
                             (fn [x]
                               (if-not
                                 (reload-spec? x)
                                 (->>
                                   x
                                   (remove-from-spec
                                     #{:include-macros})
                                   (remove-from-spec #{:refer})
                                   (remove-from-spec #{:rename})
                                   (replace-refer-macros))
                                 x)))))
        remove-sugar (partial remove-from-spec sugar-keys)]
    (if-some
      [require-specs (seq (to-macro-specs require))]
      (map
        (fn [x]
          (if-not (reload-spec? x)
            (let [[k v] x] (cons k (map remove-sugar v)))
            x))
        (update-in
          indexed
          [:require-macros]
          (fnil into [])
          require-specs))
      args)))
(defn analyze-seq
  ([env form name]
    (analyze-seq
      env
      form
      name
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([env form name opts]
    (if (:quoted? env)
      (analyze-list env form)
      (let [line (-> form meta :line)
            line (if (nil? line) (:line env) line)
            col (-> form meta :column)
            col (if (nil? col) (:column env) col)
            env (assoc env :line line :column col)]
        (let [op (first form)]
          (when (nil? op) (throw (error env "Can't call nil")))
          (let [mform (macroexpand-1 env form)]
            (if (identical? form mform)
              (analyze-seq*-wrap op env form name opts)
              (analyze env mform name opts))))))))
(defn parse-require-spec [env macros? deps aliases spec]
  (if (or (symbol? spec) (string? spec))
    (recur env macros? deps aliases [spec])
    (do
      (basic-validate-ns-spec env macros? spec)
      (let [[lib & opts] spec
            [lib js-module-provides] (if-some
                                       [js-module-name
                                        (gets
                                          (clojure.core/deref
                                            env/*compiler*)
                                          :js-module-index
                                          (str lib)
                                          :name)]
                                       [(symbol js-module-name) lib]
                                       [lib nil])
            {alias :as 
             referred :refer 
             renamed :rename 
             :or {alias (if (string? lib) (symbol (munge lib)) lib)}} (apply
                                                                        hash-map
                                                                        opts)
            referred-without-renamed (seq
                                       (remove
                                         (set (keys renamed))
                                         referred))
            [rk uk renk] (if macros?
                           [:require-macros :use-macros :rename-macros]
                           [:require :use :rename])]
        (when-not (or (symbol? alias) (nil? alias))
          (throw
            (error
              env
              (parse-ns-error-msg
                spec
                ":as must be followed by a symbol in :require / :require-macros"))))
        (when (some? alias)
          (let [alias-type (if macros? :macros :fns)
                lib' ((alias-type (clojure.core/deref aliases)) alias)]
            (when (and (some? lib') (not= lib lib'))
              (throw
                (error
                  env
                  (parse-ns-error-msg
                    spec
                    ":as alias must be unique"))))
            (swap!
              aliases
              update-in
              [alias-type]
              conj
              [alias lib]
              (when js-module-provides [js-module-provides lib]))))
        (when-not (or
                    (and
                      (sequential? referred)
                      (every? symbol? referred))
                    (nil? referred))
          (throw
            (error
              env
              (parse-ns-error-msg
                spec
                ":refer must be followed by a sequence of symbols in :require / :require-macros"))))
        (when-not macros? (swap! deps conj lib))
        (merge
          (when (some? alias)
            {rk
             (merge
               {alias lib}
               {lib lib}
               (when js-module-provides {js-module-provides lib}))})
          (when (some? referred-without-renamed)
            {uk
             (apply
               hash-map
               (interleave referred-without-renamed (repeat lib)))})
          (when (some? renamed)
            {renk
             (reduce
               (fn [m [original renamed]]
                 (when-not (some #{original} referred)
                   (throw
                     (error
                       env
                       (str
                         "Renamed symbol "
                         original
                         " not referred"))))
                 (assoc m renamed (symbol (str lib) (str original))))
               {}
               renamed)}))))))
(defn infer-tag
  "Given env, an analysis environment, and e, an AST node, return the inferred\n   type of the node"
  [env ast]
  (if-some
    [tag (get-tag ast)]
    tag
    (case
      (:op ast)
      :recur
      impl/IGNORE_SYM
      :throw
      impl/IGNORE_SYM
      :let
      (infer-tag env (:body ast))
      :loop
      (infer-tag env (:body ast))
      :do
      (infer-tag env (:ret ast))
      :fn-method
      (infer-tag env (:body ast))
      :def
      (infer-tag env (:init ast))
      :invoke
      (infer-invoke env ast)
      :if
      (infer-if env ast)
      :const
      (case
        (:form ast)
        true
        impl/BOOLEAN_SYM
        false
        impl/BOOLEAN_SYM
        impl/ANY_SYM)
      :quote
      (infer-tag env (:expr ast))
      (:var :local :js-var :binding)
      (if-some
        [init (:init ast)]
        (infer-tag env init)
        (infer-tag env (:info ast)))
      (:host-field :host-call)
      impl/ANY_SYM
      :js
      impl/ANY_SYM
      nil)))
(defmethod
  parse
  (quote letfn*)
  [op env [_ bindings & exprs :as form] name _]
  (when-not (and (vector? bindings) (even? (count bindings)))
    (throw
      (error
        env
        "bindings must be vector of even number of elements")))
  (let [n->fexpr (into
                   {}
                   (map (juxt first second) (partition 2 bindings)))
        names (keys n->fexpr)
        context (:context env)
        [meth-env bes] (reduce
                         (fn [[{:keys [locals]  :as env} bes] n]
                           (let [ret-tag (-> n meta :tag)
                                 fexpr
                                 (no-warn (analyze env (n->fexpr n)))
                                 be
                                 (cond->
                                   {:name n 
                                    :method-params
                                    (map :params (:methods fexpr)) 
                                    :op :binding 
                                    :column (get-col n env) 
                                    :variadic? (:variadic? fexpr) 
                                    :line (get-line n env) 
                                    :max-fixed-arity
                                    (:max-fixed-arity fexpr) 
                                    :fn-var true 
                                    :shadow
                                    (handle-symbol-local n (locals n)) 
                                    :local :letfn}
                                   ret-tag
                                   (assoc :ret-tag ret-tag))]
                             [(assoc-in env [:locals n] be)
                              (conj bes be)]))
                         [env []]
                         names)
        meth-env (assoc meth-env :context :expr)
        [meth-env bes] (reduce
                         (fn [[meth-env bes]
                              {:keys [name shadow]  :as be}]
                           (let [env
                                 (assoc-in
                                   meth-env
                                   [:locals name]
                                   shadow)
                                 fexpr (analyze env (n->fexpr name))
                                 be'
                                 (assoc
                                   be
                                   :init
                                   fexpr
                                   :variadic?
                                   (:variadic? fexpr)
                                   :max-fixed-arity
                                   (:max-fixed-arity fexpr)
                                   :method-params
                                   (map :params (:methods fexpr))
                                   :children
                                   [:init])]
                             [(assoc-in env [:locals name] be')
                              (conj bes be')]))
                         [meth-env []]
                         bes)
        expr (-> (analyze
                   (assoc
                     meth-env
                     :context
                     (if (= :expr context) :return context))
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list (quote do))
                       exprs)))
              (assoc :body? true))]
    {:env env 
     :op :letfn 
     :bindings bes 
     :body expr 
     :form form 
     :children [:bindings :body]}))
(defn analyze-form-seq
  ([forms]
    (analyze-form-seq
      forms
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([forms opts] (analyze-form-seq forms opts false))
  ([forms opts return-last?]
    (let [env (assoc (empty-env) :build-options opts)]
      (binding [*file-defs* nil
                *unchecked-if* false
                *unchecked-arrays* false
                *cljs-ns* (quote cljs.user)
                *cljs-file* nil
                reader/*alias-map* (or
                                     (get-bridged-alias-map)
                                     reader/*alias-map*
                                     {})]
        (loop [ns nil forms forms last-ast nil]
          (if (some? forms)
            (let [form (first forms)
                  env (assoc env :ns (get-namespace *cljs-ns*))
                  ast (analyze env form nil opts)]
              (if (= (:op ast) :ns)
                (recur (:name ast) (next forms) ast)
                (recur ns (next forms) ast)))
            (if return-last? last-ast ns)))))))
(defn type? [env t]
  (when (and (some? t) (symbol? t))
    (let [var (binding [*private-var-access-nowarn* true]
                (resolve-var env t))]
      (if-some
        [type (:type var)]
        type
        (if-some
          [type (-> var :info :type)]
          type
          (if-some
            [proto (:protocol-symbol var)]
            proto
            (get
              (quote #{cljs.core/PersistentHashMap cljs.core/List})
              t)))))))
(defn load-data-readers* []
  (let [data-readers (get-data-readers)
        nses (map (comp symbol namespace) (vals data-readers))]
    (doseq [ns nses]
      (try (locking load-mutex (require ns)) (catch Throwable _)))
    (->>
      data-readers
      (map
        (fn [[tag reader-fn]] [tag
                               (->
                                reader-fn
                                find-var
                                var-get
                                (with-meta {:sym reader-fn}))]))
      (into {}))))
(defn check-invoke-arg-types [env {:keys [op]  :as ast} opts]
  (when (and (not (analyzed? ast)) (= :invoke op))
    (when-some
      [[name {:keys [valid? warning-type]}]
       (find invoke-arg-type-validators (-> ast :fn :info :name))]
      (let [types (mapv :tag (:args ast))]
        (when-not (valid? types)
          (warning warning-type env {:name name  :types types})))))
  (analyzed ast))
(defn canonicalize-type [t]
  "Ensures that a type tag is either nil, a type symbol, or a non-singleton\n  set of type symbols, absorbing clj-nil into seq and all types into any."
  (cond
    (symbol? t) t
    (empty? t) nil
    (== 1 (count t)) (first t)
    (contains? t (quote any)) (quote any)
    (contains? t (quote seq)) (let [res (disj t (quote clj-nil))]
                                (if
                                  (== 1 (count res))
                                  (quote seq)
                                  res))
    :else t))
(defn- merge-ns-info [old new env]
  (if (pos? (count old))
    (let [deep-merge-keys [:use-macros
                           :require-macros
                           :rename-macros
                           :uses
                           :requires
                           :renames
                           :imports
                           :as-aliases]]
      (when *check-alias-dupes* (check-duplicate-aliases env old new))
      (merge
        old
        (select-keys new [:excludes])
        (merge-with
          merge
          (select-keys old deep-merge-keys)
          (select-keys new deep-merge-keys))))
    new))
(defn analyze-form [env form name opts]
  (cond
    (symbol? form) (analyze-symbol env form)
    (and (seq? form) (seq form)) (analyze-seq env form name opts)
    (record? form) (analyze-record env form)
    (map? form) (analyze-map env form)
    (vector? form) (analyze-vector env form)
    (set? form) (analyze-set env form)
    (keyword? form) (analyze-keyword env form)
    (instance? JSValue form) (analyze-js-value env form)
    :else (let [tag (cond
                      (nil? form) (quote clj-nil)
                      (number? form) (quote number)
                      (string? form) (quote string)
                      (instance? Character form) (quote string)
                      (true? form) (quote boolean)
                      (false? form) (quote boolean)
                      (= () form) (quote cljs.core/IList))]
            (cond->
              {:op :const  :val form  :env env  :form form}
              tag
              (assoc :tag tag)))))
(defn- register-constant!
  ([val] (register-constant! nil val))
  ([env val]
    (swap!
      env/*compiler*
      (fn [cenv]
        (cond->
          (-> cenv
           (update-in
             [:cljs.analyzer/constant-table]
             (fn [table]
               (if (get table val)
                 table
                 (assoc table val (gen-constant-id val))))))
          env
          (update-in
            [:cljs.analyzer/namespaces
             (-> env :ns :name)
             :cljs.analyzer/constants]
            (fn [{:keys [seen order] 
                  :or {seen #{}  order []} 
                  :as constants}]
              (cond->
                constants
                (not (contains? seen val))
                (assoc
                  :seen
                  (conj seen val)
                  :order
                  (conj order val))))))))))
(defmethod
  parse
  (quote fn*)
  [op env [_ & args :as form] name _]
  (let [named-fn? (symbol? (first args))
        [name meths] (if named-fn?
                       [(first args) (next args)]
                       [name (seq args)])
        meths (if (vector? (first meths)) (list meths) meths)
        locals (:locals env)
        name-var (fn-name-var env locals name)
        env (if (some? name)
              (update-in env [:fn-scope] conj name-var)
              env)
        locals (if (and (some? locals) named-fn?)
                 (assoc locals name name-var)
                 locals)
        form-meta (meta form)
        type (:cljs.analyzer/type form-meta)
        proto-impl (:cljs.analyzer/protocol-impl form-meta)
        proto-inline (:cljs.analyzer/protocol-inline form-meta)
        menv (-> env
              (cond-> (> (count meths) 1) (assoc :context :expr))
              (dissoc :in-loop)
              (merge
                {:protocol-impl proto-impl 
                 :protocol-inline proto-inline}))
        methods (map
                  (fn*
                    [p1__3407#]
                    (disallowing-ns*
                      (analyze-fn-method
                        menv
                        locals
                        p1__3407#
                        type
                        (nil? name))))
                  meths)
        mfa (transduce (map :fixed-arity) max 0 methods)
        variadic (boolean (some :variadic? methods))
        locals (if named-fn?
                 (update-in
                   locals
                   [name]
                   assoc
                   :fn-var
                   true
                   :variadic?
                   variadic
                   :max-fixed-arity
                   mfa
                   :method-params
                   (map :params methods))
                 locals)
        methods (if (some? name)
                  (disallowing-ns*
                    (analyze-fn-methods-pass2 menv locals type meths))
                  (vec methods))
        form (vary-meta
               form
               dissoc
               :cljs.analyzer/protocol-impl
               :cljs.analyzer/protocol-inline
               :cljs.analyzer/type)
        js-doc (when (true? variadic) "@param {...*} var_args")
        children (if (some? name-var) [:local :methods] [:methods])
        inferred-ret-tag (let [inferred-tags (map
                                               (partial infer-tag env)
                                               (map :body methods))]
                           (when (apply = inferred-tags)
                             (first inferred-tags)))
        ast (merge
              {:children children 
               :protocol-inline proto-inline 
               :name name-var 
               :loop-lets *loop-lets* 
               :inferred-ret-tag inferred-ret-tag 
               :protocol-impl proto-impl 
               :op :fn 
               :env env 
               :variadic? variadic 
               :methods methods 
               :recur-frames *recur-frames* 
               :max-fixed-arity mfa 
               :form form 
               :tag (quote function) 
               :in-loop (:in-loop env) 
               :jsdoc [js-doc]}
              (when (some? name-var) {:local name-var}))]
    (let [variadic-methods (into
                             []
                             (comp (filter :variadic?) (take 1))
                             methods)
          variadic-params (if (pos? (count variadic-methods))
                            (count (:params (nth variadic-methods 0)))
                            0)
          param-counts (into [] (map (comp count :params)) methods)]
      (when (< 1 (count variadic-methods))
        (warning :multiple-variadic-overloads env {:name name-var}))
      (when (not
              (or
                (zero? variadic-params)
                (== variadic-params (+ 1 mfa))))
        (warning :variadic-max-arity env {:name name-var}))
      (when (not= (distinct param-counts) param-counts)
        (warning :overload-arity env {:name name-var})))
    (analyze-wrap-meta ast)))
(defn use->require [env [lib & filters :as spec]]
  (when-not (and (symbol? lib) (odd? (count spec)))
    (throw
      (error
        env
        (parse-ns-error-msg
          spec
          "Only [lib.ns :only (names)] and optionally `:rename {from to}` specs supported in :use / :use-macros"))))
  (loop [fs (seq filters) ret [lib] err false]
    (cond
      (true? err) (throw
                    (error
                      env
                      (parse-ns-error-msg
                        spec
                        "Only [lib.ns :only (names)] and optionally `:rename {from to}` specs supported in :use / :use-macros")))
      (some? fs) (let [kw (first fs) only? (= kw :only)]
                   (if (or only? (= kw :rename))
                     (if (some? (some #{(if only? :refer kw)} ret))
                       (throw
                         (error
                           env
                           (parse-ns-error-msg
                             spec
                             "Each of :only and :rename options may only be specified once in :use / :use-macros")))
                       (let [refs (second fs)]
                         (if-not (or
                                   (and
                                     only?
                                     (sequential? refs)
                                     (every? symbol? refs))
                                   (and
                                     (= kw :rename)
                                     (map? refs)
                                     (every?
                                       (fn*
                                         [p1__3746#]
                                         (every? symbol? p1__3746#))
                                       refs)))
                           (recur fs ret true)
                           (recur
                             (nnext fs)
                             (into ret [(if only? :refer kw) refs])
                             false))))
                     (recur fs ret true)))
      :else (if (some? (some #{:refer} ret)) ret (recur fs ret true)))))
(defn parse-invoke* [env [f & args :as form]]
  (let [enve (assoc env :context :expr)
        fexpr (analyze enve f)
        argc (count args)
        fn-var? (or
                  (-> fexpr :info :fn-var)
                  (-> fexpr :info :js-fn-var))
        kw? (= (quote cljs.core/Keyword) (:tag fexpr))
        cur-ns (-> env :ns :name)
        HO-invoke? (and
                     (boolean *cljs-static-fns*)
                     (not fn-var?)
                     (not (js-tag? f))
                     (not kw?)
                     (not (analyzed? f)))
        bind-f-expr? (and HO-invoke? (not (symbol? f)))
        bind-args? (and HO-invoke? (not (all-values? args)))]
    (when fn-var?
      (let [{variadic :variadic? 
             :keys [max-fixed-arity method-params name ns macro]} (:info
                                                                    fexpr)]
        (when (and
                (invalid-arity?
                  argc
                  method-params
                  variadic
                  max-fixed-arity))
          (warning :fn-arity env {:name name  :argc argc}))))
    (when (and kw? (not (or (== 1 argc) (== 2 argc))))
      (warning :fn-arity env {:name (first form)  :argc argc}))
    (let [deprecated? (-> fexpr :info :deprecated)
          no-warn? (-> form meta :deprecation-nowarn)]
      (when (and (boolean deprecated?) (not (boolean no-warn?)))
        (warning :fn-deprecated env {:fexpr fexpr})))
    (when (some? (-> fexpr :info :type))
      (warning :invoke-ctor env {:fexpr fexpr}))
    (if (or bind-args? bind-f-expr?)
      (let [arg-syms (when bind-args? (take argc (repeatedly gensym)))
            f-sym (when bind-f-expr? (gensym "fexpr__"))
            bindings (cond->
                       []
                       bind-args?
                       (into (interleave arg-syms args))
                       bind-f-expr?
                       (conj f-sym (analyzed f)))
            tag (:tag (meta form))]
        (analyze
          env
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/let))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq (clojure.core/concat bindings))))
              (clojure.core/list
                (with-meta
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (analyzed (if bind-f-expr? f-sym f)))
                      (if bind-args? arg-syms args)))
                  {:tag tag}))))))
      (let [ana-expr (fn* [p1__4175#] (analyze enve p1__4175#))
            argexprs (mapv ana-expr args)]
        (if (and
              (and (keyword? f) (nil? (namespace f)))
              (== 1 (count args))
              (record-with-field?
                (:tag (first argexprs))
                (symbol (name f))))
          (let [field-access-form (list*
                                    (symbol (str ".-" (name f)))
                                    args)]
            (no-warn (analyze env field-access-form)))
          {:env env 
           :op :invoke 
           :form form 
           :fn fexpr 
           :args argexprs 
           :children [:fn :args]})))))
(defn get-expander-ns [env nstr]
  (let [res (or
              (resolve-macro-ns-alias env nstr nil)
              (resolve-ns-alias env nstr nil))
        nstr (if (some? res) (str res) nstr)]
    (cond
      (= "clojure.core" nstr) (find-ns (quote cljs.core))
      (= "clojure.repl" nstr) (find-ns (quote cljs.repl))
      (.contains nstr ".") (find-ns (symbol nstr))
      :else (some->
              env
              :ns
              :require-macros
              (get (symbol nstr))
              find-ns))))
(defmethod
  parse
  (quote js*)
  [op env [_ jsform & args :as form] _ _]
  (when-not (string? jsform) (throw (error env "Invalid js* form")))
  (if (some? args)
    (analyze-js-star env jsform args form)
    (let [code (apply str (js-star-interp env jsform))
          tag (get-js-tag form)
          form-meta (meta form)
          js-op (:js-op form-meta)
          numeric (:numeric form-meta)]
      {:op :js 
       :env env 
       :form form 
       :code code 
       :tag tag 
       :js-op js-op 
       :numeric numeric})))
(defmethod
  parse
  (quote try)
  [op env [_ & body :as form] name _]
  (let [catchenv (update-in
                   env
                   [:context]
                   (fn*
                     [p1__3272#]
                     (if (= :expr p1__3272#) :return p1__3272#)))
        catch? (every-pred
                 seq?
                 (fn* [p1__3273#] (= (first p1__3273#) (quote catch))))
        default? (every-pred
                   catch?
                   (fn* [p1__3274#] (= (second p1__3274#) :default)))
        finally? (every-pred
                   seq?
                   (fn*
                     [p1__3275#]
                     (= (first p1__3275#) (quote finally))))
        {:keys [body cblocks dblock fblock]} (loop 
                                               [parser
                                                {:state :start 
                                                 :forms body 
                                                 :body [] 
                                                 :cblocks [] 
                                                 :dblock nil 
                                                 :fblock nil}]
                                               (if
                                                 (seq? (:forms parser))
                                                 (let 
                                                   [[form & forms*]
                                                    (:forms parser)
                                                    parser*
                                                    (assoc
                                                      parser
                                                      :forms
                                                      forms*)]
                                                   (case
                                                     (:state parser)
                                                     :start
                                                     (cond
                                                       (catch? form)
                                                       (recur
                                                         (assoc
                                                           parser
                                                           :state
                                                           :catches))
                                                       (finally? form)
                                                       (recur
                                                         (assoc
                                                           parser
                                                           :state
                                                           :finally))
                                                       :else
                                                       (recur
                                                         (update-in
                                                           parser*
                                                           [:body]
                                                           conj
                                                           form)))
                                                     :catches
                                                     (cond
                                                       (default? form)
                                                       (recur
                                                         (assoc
                                                           parser*
                                                           :dblock
                                                           form
                                                           :state
                                                           :finally))
                                                       (catch? form)
                                                       (recur
                                                         (update-in
                                                           parser*
                                                           [:cblocks]
                                                           conj
                                                           form))
                                                       (finally? form)
                                                       (recur
                                                         (assoc
                                                           parser
                                                           :state
                                                           :finally))
                                                       :else
                                                       (throw
                                                         (error
                                                           env
                                                           "Invalid try form")))
                                                     :finally
                                                     (recur
                                                       (assoc
                                                         parser*
                                                         :fblock
                                                         form
                                                         :state
                                                         :done))
                                                     :done
                                                     (throw
                                                       (error
                                                         env
                                                         "Unexpected form after finally"))))
                                                 parser))
        finally (when (seq fblock)
                  (-> (disallowing-recur
                        (analyze
                          (assoc env :context :statement)
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote do))
                              (rest fblock)))))
                   (assoc :body? true)))
        e (when (or (seq cblocks) dblock) (gensym "e"))
        default (if-let [[_ _ name & cb] dblock]
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/let))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list name)
                              (clojure.core/list e)))))
                      cb))
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote throw))
                      (clojure.core/list e))))
        cblock (if (seq cblocks)
                 (clojure.core/seq
                   (clojure.core/concat
                     (clojure.core/list (quote cljs.core/cond))
                     (mapcat
                       (fn [[_ type name & cb]]
                         (when name
                           (assert
                             (not (namespace name))
                             "Can't qualify symbol in catch"))
                         (clojure.core/apply
                           clojure.core/vector
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list
                                       (quote cljs.core/instance?))
                                     (clojure.core/list type)
                                     (clojure.core/list e))))
                               (clojure.core/list
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list
                                       (quote cljs.core/let))
                                     (clojure.core/list
                                       (clojure.core/apply
                                         clojure.core/vector
                                         (clojure.core/seq
                                           (clojure.core/concat
                                             (clojure.core/list name)
                                             (clojure.core/list e)))))
                                     cb)))))))
                       cblocks)
                     (clojure.core/list :else)
                     (clojure.core/list default)))
                 default)
        locals (:locals catchenv)
        locals (if e
                 (assoc
                   locals
                   e
                   {:name e 
                    :line (get-line e env) 
                    :column (get-col e env)})
                 locals)
        catch (when cblock
                (disallowing-recur
                  (analyze (assoc catchenv :locals locals) cblock)))
        try (disallowing-recur
              (analyze
                (if (or e finally) catchenv env)
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote do))
                    body))))]
    {:env env 
     :op :try 
     :form form 
     :body (assoc try :body? true) 
     :finally finally 
     :name e 
     :catch catch 
     :children
     (vec
       (concat
         [:body]
         (when catch [:catch])
         (when finally [:finally])))}))
(defn clj-ns->cljs-ns
  "Given a symbol that starts with clojure as the first segment return the\n   same symbol with the first segment replaced with cljs"
  [sym]
  (let [segs (string/split (clojure.core/name sym) #"\.")]
    (if (= "clojure" (first segs))
      (symbol (string/join "." (cons "cljs" (next segs))))
      sym)))
(defn analyze-let-bindings* [encl-env bindings op]
  (loop [bes []
         env (assoc encl-env :context :expr)
         bindings (seq (partition 2 bindings))]
    (if-some
      [[name init] (first bindings)]
      (let []
        (when (or (some? (namespace name)) (.contains (str name) "."))
          (throw (error encl-env (str "Invalid local name: " name))))
        (let [init-expr (analyze-let-binding-init
                          env
                          init
                          (cons {:params bes} *loop-lets*))
              line (get-line name env)
              col (get-col name env)
              shadow (or
                       (handle-symbol-local
                         name
                         (get-in env [:locals name]))
                       (get-in env [:js-globals name]))
              be {:children [:init] 
                  :init init-expr 
                  :name name 
                  :binding-form? true 
                  :op :binding 
                  :env {:line line  :column col} 
                  :column col 
                  :line line 
                  :info {:name name  :shadow shadow} 
                  :tag (get-let-tag name init-expr) 
                  :shadow shadow 
                  :local op}
              be (if (= :fn (:op init-expr))
                   (merge
                     be
                     {:fn-var true 
                      :methods
                      (into
                        []
                        (map
                          (fn*
                            [p1__3476#]
                            (select-keys
                              p1__3476#
                              [:tag :fixed-arity :variadic?]))
                          (:methods init-expr))) 
                      :variadic? (:variadic? init-expr) 
                      :max-fixed-arity (:max-fixed-arity init-expr) 
                      :method-params
                      (map :params (:methods init-expr))})
                   be)]
          (recur
            (conj bes be)
            (assoc-in env [:locals name] be)
            (next bindings))))
      [bes env])))
(defn parse-ns-excludes [env args]
  (reduce
    (fn [s [k & filters]]
      (if (= k :refer-clojure)
        (do
          (when (seq (:excludes s))
            (throw
              (error
                env
                "Only one :refer-clojure form is allowed per namespace definition")))
          (let [valid-kws #{:exclude :rename}
                xs (loop [fs (seq filters)
                          ret {:excludes #{}  :renames {}}
                          err (not (even? (count filters)))]
                     (cond
                       (true? err) (throw
                                     (error
                                       env
                                       "Only [:refer-clojure :exclude (names)] and optionally `:rename {from to}` specs supported"))
                       (some? fs) (let 
                                    [kw (first fs)]
                                    (if
                                      (valid-kws kw)
                                      (let 
                                        [refs (second fs)]
                                        (cond
                                          (not
                                            (or
                                              (and
                                                (= kw :exclude)
                                                (sequential? refs)
                                                (every? symbol? refs))
                                              (and
                                                (= kw :rename)
                                                (map? refs)
                                                (every?
                                                  (fn*
                                                    [p1__3729#]
                                                    (every?
                                                      symbol?
                                                      p1__3729#))
                                                  refs))))
                                          (recur fs ret true)
                                          (= kw :exclude)
                                          (recur
                                            (nnext fs)
                                            (update-in
                                              ret
                                              [:excludes]
                                              into
                                              refs)
                                            false)
                                          (= kw :rename)
                                          (recur
                                            (nnext fs)
                                            (update-in
                                              ret
                                              [:renames]
                                              merge
                                              refs)
                                            false)))
                                      (recur fs ret true)))
                       :else ret))]
            (merge-with into s xs)))
        s))
    {:excludes #{}  :renames {}}
    args))
(defn analyze-fn-method-param [env]
  (fn [[locals params] [arg-id name]]
    (when (namespace name)
      (throw
        (error
          env
          (str "Can't use qualified name as parameter: " name))))
    (let [line (get-line name env)
          column (get-col name env)
          nmeta (meta name)
          tag (:tag nmeta)
          shadow (when (some? locals)
                   (handle-symbol-local name (locals name)))
          env (merge
                (select-keys env [:context])
                {:line line  :column column})
          param {:name name 
                 :binding-form? true 
                 :op :binding 
                 :env env 
                 :column column 
                 :line line 
                 :arg-id arg-id 
                 :info {:name name  :shadow shadow} 
                 :tag tag 
                 :shadow shadow 
                 :local :arg}]
      [(assoc locals name param) (conj params param)])))
(defn parse-ns
  "Helper for parsing only the essential namespace information from a\n      ClojureScript source file and returning a cljs.closure/IJavaScript compatible\n      map _not_ a namespace AST node.\n\n      By default does not load macros or perform any analysis of dependencies. If\n      opts parameter provided :analyze-deps and :load-macros keys their values will\n      be used for *analyze-deps* and *load-macros* bindings respectively. This\n      function does _not_ side-effect the ambient compilation environment unless\n      requested via opts where :restore is false."
  ([src]
    (parse-ns
      src
      nil
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([src opts] (parse-ns src nil opts))
  ([src dest opts]
    (ensure
      (let [src (if (symbol? src) (util/ns->source src) src)
            ijs (binding [env/*compiler* (if
                                           (false? (:restore opts))
                                           env/*compiler*
                                           (atom
                                             (clojure.core/deref
                                               env/*compiler*)))
                          *cljs-ns* (quote cljs.user)
                          *cljs-file* src
                          *macro-infer* (or
                                          (when
                                            (contains?
                                              opts
                                              :macro-infer)
                                            (:macro-infer opts))
                                          false)
                          *analyze-deps* (or
                                           (when
                                             (contains?
                                               opts
                                               :analyze-deps)
                                             (:analyze-deps opts))
                                           false)
                          *load-macros* (or
                                          (when
                                            (contains?
                                              opts
                                              :load-macros)
                                            (:load-macros opts))
                                          false)]
                  (let [rdr (when-not (sequential? src)
                              (io/reader src))]
                    (try
                      (loop [forms (if
                                     rdr
                                     (forms-seq* rdr (source-path src))
                                     src)
                             ret (merge
                                   {:file dest 
                                    :source-file (when rdr src) 
                                    :source-forms (when-not rdr src) 
                                    :macros-ns (:macros-ns opts) 
                                    :requires
                                    (cond->
                                      #{(quote cljs.core)}
                                      (get-in
                                        (clojure.core/deref
                                          env/*compiler*)
                                        [:options :emit-constants])
                                      (conj constants-ns-sym))}
                                   (when
                                     (and dest (.exists dest))
                                     {:lines
                                      (with-open 
                                        [reader (io/reader dest)]
                                        (-> reader line-seq count))}))]
                        (if (seq forms)
                          (let [env (empty-env)
                                ast
                                (no-warn
                                  (analyze
                                    env
                                    (first forms)
                                    nil
                                    opts))]
                            (cond
                              (= :ns (:op ast)) (let 
                                                  [ns-name (:name ast)
                                                   ns-name
                                                   (if
                                                     (and
                                                       (=
                                                         (quote
                                                           cljs.core)
                                                         ns-name)
                                                       (=
                                                         "cljc"
                                                         (util/ext
                                                           src)))
                                                     (quote
                                                       cljs.core$macros)
                                                     ns-name)
                                                   deps
                                                   (merge
                                                     (:uses ast)
                                                     (:requires ast))]
                                                  (merge
                                                    {:ns
                                                     (or
                                                       ns-name
                                                       (quote
                                                         cljs.user)) 
                                                     :provides
                                                     [ns-name] 
                                                     :requires
                                                     (if
                                                       (=
                                                         (quote
                                                           cljs.core)
                                                         ns-name)
                                                       (set
                                                         (vals deps))
                                                       (cond->
                                                         (conj
                                                           (set
                                                             (vals
                                                               deps))
                                                           (quote
                                                             cljs.core))
                                                         (get-in
                                                           (clojure.core/deref
                                                             env/*compiler*)
                                                           [:options
                                                            :emit-constants])
                                                         (conj
                                                           constants-ns-sym))) 
                                                     :file dest 
                                                     :source-file
                                                     (when rdr src) 
                                                     :source-forms
                                                     (when-not
                                                       rdr
                                                       src) 
                                                     :ast ast 
                                                     :macros-ns
                                                     (or
                                                       (:macros-ns
                                                         opts)
                                                       (=
                                                         (quote
                                                           cljs.core$macros)
                                                         ns-name))}
                                                    (when
                                                      (and
                                                        dest
                                                        (.exists dest))
                                                      {:lines
                                                       (with-open 
                                                         [reader
                                                          (io/reader
                                                            dest)]
                                                         (->
                                                          reader
                                                          line-seq
                                                          count))})))
                              (= :ns* (:op ast)) (let 
                                                   [deps
                                                    (merge
                                                      (:uses ast)
                                                      (:requires ast))]
                                                   (recur
                                                     (rest forms)
                                                     (cond->
                                                       (update-in
                                                         ret
                                                         [:requires]
                                                         into
                                                         (set
                                                           (vals
                                                             deps)))
                                                       (not (:ns ret))
                                                       (assoc
                                                         :ns
                                                         (gen-user-ns
                                                           src)
                                                         :provides
                                                         [(gen-user-ns
                                                            src)]))))
                              :else ret))
                          ret))
                      (finally (when rdr (.close rdr))))))]
        (cond->
          ijs
          (not (contains? ijs :ns))
          (merge
            {:ns (gen-user-ns src)  :provides [(gen-user-ns src)]}))))))
(defn analyze-js-star* [env jsform args form]
  (let [enve (assoc env :context :expr)
        form-meta (meta form)
        segs (js-star-seg jsform)
        tag (get-js-tag form)
        js-op (:js-op form-meta)
        argexprs (analyze-js-star-args js-op enve args)
        numeric (:numeric form-meta)
        validate (fn [warning-type valid-types?]
                   (let [types (map
                                 (fn*
                                   [p1__4130#]
                                   (infer-tag env p1__4130#))
                                 argexprs)]
                     (when-not (valid-types? types)
                       (warning
                         warning-type
                         env
                         {:js-op js-op  :types (into [] types)}))))
        op-match? (fn [sym] (= sym (:js-op form-meta)))]
    (when (true? numeric)
      (validate
        :invalid-arithmetic
        (fn* [p1__4131#] (every? numeric-type? p1__4131#))))
    {:args argexprs 
     :children [:args] 
     :numeric numeric 
     :segs segs 
     :op :js 
     :env env 
     :js-op js-op 
     :form form 
     :tag tag}))
(defn gen-constant-id [value]
  (let [prefix (cond
                 (keyword? value) "cst$kw$"
                 (symbol? value) "cst$sym$"
                 :else (throw
                         (Exception.
                           (str
                             "constant type "
                             (type value)
                             " not supported"))))
        name (if (keyword? value) (subs (str value) 1) (str value))
        name (if (= "." name)
               "_DOT_"
               (-> name
                (string/replace "-" "_DASH_")
                (munge)
                (string/replace "." "$")
                (string/replace
                  #"(?i)[^a-z0-9$_]"
                  (fn* [p1__2818#] (hex-format p1__2818# 4)))))]
    (symbol (str prefix name))))
(defn parse-import-spec [env deps spec]
  (when-not (or
              (and (sequential? spec) (every? symbol? spec))
              (and (symbol? spec) (nil? (namespace spec))))
    (throw
      (error
        env
        (parse-ns-error-msg
          spec
          "Only lib.ns.Ctor or [lib.ns Ctor*] spec supported in :import"))))
  (let [import-map (cond
                     (sequential? spec) (->>
                                          (rest spec)
                                          (map
                                            (fn*
                                              [p1__3784#]
                                              (vector
                                                p1__3784#
                                                (symbol
                                                  (str
                                                    (first spec)
                                                    "."
                                                    p1__3784#)))))
                                          (into {}))
                     (not (== -1 (.indexOf (str spec) "."))) {(symbol
                                                                (last
                                                                  (string/split
                                                                    (str
                                                                      spec)
                                                                    #"\.")))
                                                              spec}
                     :else {})]
    (doseq [[_ spec] import-map] (swap! deps conj spec))
    {:import import-map  :require import-map}))
(defn resolve-import
  "goog.modules are deterministically assigned to a property of the namespace,\n   we cannot expect the reference will be globally available, so we resolve to\n   namespace local reference."
  [env import]
  (if (goog-module-dep? import)
    (symbol (munge-goog-module-lib (-> env :ns :name) import))
    import))
(defmethod
  parse
  (quote def)
  [op env form _ _]
  (when (> (count form) 4)
    (throw (error env "Too many arguments to def")))
  (let [pfn (fn ([_ sym] {:sym sym})
              ([_ sym init] {:sym sym  :init init})
              ([_ sym doc init] {:sym sym  :doc doc  :init init}))
        args (apply pfn form)
        sym (:sym args)
        const? (-> sym meta :const)
        sym-meta (meta sym)
        tag (-> sym meta :tag)
        protocol (-> sym meta :protocol valid-proto)
        dynamic (-> sym meta :dynamic)
        ns-name (-> env :ns :name)
        locals (:locals env)
        clash-ns (symbol (str ns-name "." sym))
        sym-ns (namespace sym)
        sym (cond
              (and sym-ns (not (= (symbol sym-ns) ns-name))) (throw
                                                               (error
                                                                 env
                                                                 (str
                                                                   "Can't def ns-qualified name in namespace "
                                                                   sym-ns)))
              (some? sym-ns) (symbol (name sym))
              :else sym)]
    (when (some?
            (get-in
              (clojure.core/deref env/*compiler*)
              [:cljs.analyzer/namespaces clash-ns]))
      (warning
        :ns-var-clash
        env
        {:ns (symbol (str ns-name "." sym)) 
         :var (symbol (str ns-name) (str sym))}))
    (when (some? (:const (resolve-var (dissoc env :locals) sym)))
      (throw (error env "Can't redefine a constant")))
    (when-some
      [doc (:doc args)]
      (when-not (string? doc)
        (throw (error env "Too many arguments to def"))))
    (when (and (not dynamic) (earmuffed? sym) (not (core-ns? ns-name)))
      (warning :non-dynamic-earmuffed-var env {:var (str sym)}))
    (when-some
      [v
       (get-in
         (clojure.core/deref env/*compiler*)
         [:cljs.analyzer/namespaces ns-name :defs sym])]
      (when (and
              (not *allow-redef*)
              (not (:declared v))
              (not (:declared sym-meta))
              *file-defs*
              (get (clojure.core/deref *file-defs*) sym))
        (warning :redef-in-file env {:sym sym  :line (:line v)}))
      (when (and
              (:declared v)
              (:arglists v)
              (not= (:arglists v) (:arglists sym-meta)))
        (warning
          :declared-arglists-mismatch
          env
          {:ns-name ns-name 
           :sym sym 
           :declared (second (:arglists v)) 
           :defined (second (:arglists sym-meta))})))
    (let [env (if (or
                    (and
                      (not= ns-name (quote cljs.core))
                      (core-name? env sym))
                    (some?
                      (get-in
                        (clojure.core/deref env/*compiler*)
                        [:cljs.analyzer/namespaces
                         ns-name
                         :uses
                         sym])))
                (let [ev (resolve-existing-var
                           (dissoc env :locals)
                           (with-meta
                             sym
                             {:cljs.analyzer/no-resolvetrue}))conj-to-set              (fnilconj#{ })](when(public-name?              (:nsev)sym)(warning :redefenv{:sym                    sym:ns(:ns                     ev):ns-name                  ns-name                   }))(swap!  env/*compiler*update-in[:cljs.analyzer/namespaces   ns-name                    :excludes]conj-to-set              sym)(update-in                env[:ns:excludes]conj-to-setsym))env)var-name
                    (:name(resolve-var              (dissoc                env:locals )sym))init-expr(when(contains?args:init               )(swap!        env/*compiler*assoc-in[:cljs.analyzer/namespacesns-name
          :defssym] (merge{:namevar-name} sym-meta                     (when(
                        true?dynamic){
                        :dynamic
                        true})(source-infovar-name env)))( disallowing-recur                  (disallowing-ns*                 (analyze(assocenv                          :context
                          :expr )(:initargs)sym ))))fn-var?(and(
                          some?init-expr)(=(:op init-expr                    ):fn))tag(condfn-var?                      (or(:ret-taginit-expr                      )tag(:inferred-ret-tag               init-expr) )tagtagdynamicimpl/ANY_SYM                  :else( :taginit-expr                     ))export-as       (when-let[export-val(->symmeta :export )](if(=trueexport-val      )var-name
                export-val)
                          )doc(or(:docargs)(->
                          sym
                          meta:doc))](when-some[v(get-in
                (clojure.core/deref     env/*compiler*)[:cljs.analyzer/namespacesns-name :defssym])]
          (when(and (not(->symmeta:declared)) (and(true?(:fn-var
                      v)) (notfn-var?)))(warning:fn-varenv{:ns-name
          ns-name :symsym}))) (when(or(nil?(get-in
      (clojure.core/derefenv/*compiler*)[:cljs.analyzer/namespacesns-name:defssym]))(not(:declared     sym-meta)))(when*file-defs*(swap!*file-defs*conj        sym)) (swap!               env/*compiler*assoc-in[:cljs.analyzer/namespacesns-name:defssym](merge {:namevar-name}
          (cond->sym-meta( :testsym-meta )(assoc  :testtrue)){
      :meta (->
              sym-meta              (dissoc
                  :test)(update-in[:file](fn[f](if(=(
                  ->env:ns:name)(quotecljs.core))"cljs/core.cljs"
              f))) )}(whendoc {:docdoc})(
        whenconst?(let[const-expr(binding[*passes*(conj
        *passes*         (replace-env-pass        {:context          :expr}))](analyzeenv(:init args))) ](when(constant-value?const-expr        ){:const-exprconst-expr      })))(when(true?dynamic) {:dynamic true}) (source-info
            var-name            env )(whenprotocol         {:protocolprotocol           })(when-let                [protocol-symbol        (-> sym
                  meta:protocol-symbol)]{:protocol-symbolprotocol-symbol           :info(->protocol-symbol              meta:protocol-info ):impls#{ }})(whenfn-var?         (let[ params
              (map (fn*[p1__3340#](vec( 
                                 map:name(
                                  :params                                   p1__3340#                                    ))))(:methodsinit-expr                                  ))](merge {:fn-var(
                                 not(:macrosym-meta) ):protocol-impl          (:protocol-implinit-expr):protocol-inline            (:protocol-inlineinit-expr)
            }(if-some[top-fn-meta (:top-fnsym-meta
            )]top-fn-meta{:variadic?(:variadic?    init-expr):max-fixed-arity(:max-fixed-arity      init-expr ):method-paramsparams:arglists(:arglistssym-meta
              ):arglists-meta(doall(mapmeta(:arglists           sym-meta) ))}))))(when(and(:declaredsym-meta)( 
               :arglistssym-meta        )){:declaredtrue            :fn-vartrue:method-params                      (second                             (:arglistssym-meta                         ))}) (if( andfn-var?(some?tag)){:ret-tag                            tag}(when tag{:tagtag}
                )))))(
                  merge{:envenv :op:def :formform:ns                   ns-name:namevar-name:var(assoc (analyze(->
                   env(dissoc:locals)(assoc:context:expr)(assoc:def-var             true))sym                    ):op:var):docdoc:jsdoc(:jsdocsym-meta                )}(when-let
                    [goog-type( :goog-definesym-meta)] 
                     {:goog-definegoog-type})(when(true?(:def-emits-var                  env)){:var-ast (var-ast                     envsym)}) (when-some [test(:test                     sym-meta)]{:test                    (analyze(assocenv:context:expr)test)})(when(
            some? tag) (iffn-var? {:ret-tag tag}{:tagtag}))(when(
              true?dynamic){:dynamic          true})( when 
               (some?export-as){:exportexport-as })(if(some?init-expr     ){:initinit-expr :children[:var             :init]}{:children            [:var ]}) ))))
(defmethod
  parse
  (quote if)
  [op env [_ test then else :as form] name _]
  (when (< (count form) 3)
    (throw
      (compile-syntax-error env "Too few arguments to if" (quote if))))
  (when (> (count form) 4)
    (throw
      (compile-syntax-error
        env
        "Too many arguments to if"
        (quote if))))
  (let [test-expr (disallowing-recur
                    (analyze (assoc env :context :expr) test))
        then-expr (allowing-redef
                    (analyze (set-test-induced-tags env test) then))
        else-expr (allowing-redef (analyze env else))]
    {:env env 
     :op :if 
     :form form 
     :test test-expr 
     :then then-expr 
     :else else-expr 
     :unchecked *unchecked-if* 
     :children [:test :then :else]}))
(defn source-info
  ([env] (when (:line env) (source-info nil env)))
  ([name env]
    (cond->
      {:file
       (if (= (-> env :ns :name) (quote cljs.core))
         "cljs/core.cljs"
         *cljs-file*) 
       :line (get-line name env) 
       :column (get-col name env)}
      (:root-source-info env)
      (merge (select-keys env [:root-source-info])))))
(defn analyze-file
  "Given a java.io.File, java.net.URL or a string identifying a resource on the\n      classpath attempt to analyze it.\n\n      This function side-effects the ambient compilation environment\n      `cljs.env/*compiler*` to aggregate analysis information. opts argument is\n      compiler options, if :cache-analysis true will cache analysis to\n      \":output-dir/some/ns/foo.cljs.cache.edn\". This function does not return a\n      meaningful value."
  ([f]
    (analyze-file
      f
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([f opts] (analyze-file f false opts))
  ([f skip-cache opts]
    (binding [*file-defs* (atom #{})
              *unchecked-if* false
              *unchecked-arrays* false
              *cljs-warnings* *cljs-warnings*]
      (let [output-dir (util/output-directory opts)
            res (cond
                  (instance? File f) f
                  (instance? URL f) f
                  (re-find #"^file://" f) (URL. f)
                  :else (io/resource f))]
        (assert res (str "Can't find " f " in classpath"))
        (ensure
          (let [ns-info (parse-ns res)
                path (if (instance? File res)
                       (.getPath res)
                       (.getPath res))
                cache (when (:cache-analysis opts)
                        (cache-file
                          res
                          ns-info
                          output-dir
                          :read
                          opts))]
            (when-not (get-in
                        (clojure.core/deref env/*compiler*)
                        [:cljs.analyzer/namespaces
                         (:ns ns-info)
                         :defs])
              (if (or
                    skip-cache
                    (not cache)
                    (requires-analysis? res cache output-dir opts))
                (binding [*cljs-ns* (quote cljs.user)
                          *cljs-file* path
                          reader/*alias-map* (or
                                               (get-bridged-alias-map)
                                               reader/*alias-map*
                                               {})]
                  (when (or *verbose* (:verbose opts))
                    (util/debug-prn "Analyzing" (str res)))
                  (let [env (assoc (empty-env) :build-options opts)
                        ns (with-open [rdr (io/reader res)]
                             (loop [ns nil
                                    forms
                                    (seq
                                      (forms-seq*
                                        rdr
                                        (util/path res)))]
                               (if
                                 forms
                                 (let 
                                   [form (first forms)
                                    env
                                    (assoc
                                      env
                                      :ns
                                      (get-namespace *cljs-ns*))
                                    ast (analyze env form nil opts)]
                                   (cond
                                     (= (:op ast) :ns)
                                     (recur (:name ast) (next forms))
                                     (and (nil? ns) (= (:op ast) :ns*))
                                     (recur
                                       (gen-user-ns res)
                                       (next forms))
                                     :else (recur ns (next forms))))
                                 ns)))]
                    (ensure-defs ns)
                    (when (and cache (true? (:cache-analysis opts)))
                      (write-analysis-cache ns cache res))))
                (try
                  (read-analysis-cache cache res opts)
                  (catch
                    Throwable
                    e
                    (analyze-file f true opts)))))))))))
(defmethod
  parse
  (quote set!)
  [_ env [_ target val alt :as form] _ _]
  (let [[target val] (if alt
                       [(clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote .))
                            (clojure.core/list target)
                            (clojure.core/list val)))
                        alt]
                       [target val])]
    (disallowing-recur
      (binding [*private-var-access-nowarn* true]
        (let [enve (assoc env :context :expr)
              texpr (cond
                      (symbol? target) (do
                                         (cond
                                           (and
                                             (=
                                               target
                                               (quote *unchecked-if*))
                                             (or
                                               (true? val)
                                               (false? val)))
                                           (set! *unchecked-if* val)
                                           (and
                                             (=
                                               target
                                               (quote
                                                 *unchecked-arrays*))
                                             (or
                                               (true? val)
                                               (false? val)))
                                           (set!
                                             *unchecked-arrays*
                                             val)
                                           (and
                                             (=
                                               target
                                               (quote *warn-on-infer*))
                                             (or
                                               (true? val)
                                               (false? val)))
                                           (set!
                                             *cljs-warnings*
                                             (assoc
                                               *cljs-warnings*
                                               :infer-warning
                                               val)))
                                         (when
                                           (some?
                                             (:const
                                               (resolve-var
                                                 (dissoc env :locals)
                                                 target)))
                                           (throw
                                             (error
                                               env
                                               "Can't set! a constant")))
                                         (let 
                                           [local
                                            (handle-symbol-local
                                              target
                                              (-> env :locals target))]
                                           (when-not
                                             (or
                                               (nil? local)
                                               (and
                                                 (:field local)
                                                 (or
                                                   (:mutable local)
                                                   (:unsynchronized-mutable
                                                     local)
                                                   (:volatile-mutable
                                                     local))))
                                             (throw
                                               (error
                                                 env
                                                 "Can't set! local var or non-mutable field"))))
                                         (analyze-symbol enve target))
                      :else (when (seq? target)
                              (let [texpr
                                    (if
                                      (-> target meta :extend-type)
                                      (binding 
                                        [*cljs-warnings*
                                         (assoc
                                           *cljs-warnings*
                                           :infer-warning
                                           false)]
                                        (analyze-seq enve target nil))
                                      (analyze-seq enve target nil))]
                                (when (:field texpr) texpr))))
              vexpr (analyze enve val)]
          (when (seq? target)
            (let [sym (some-> target second) meta (meta sym)]
              (when-let [info (and (= :fn (:op vexpr)) (:top-fn meta))]
                (swap!
                  env/*compiler*
                  update-in
                  [:cljs.analyzer/namespaces
                   (-> env :ns :name)
                   :defs
                   sym
                   :methods]
                  (fnil conj [])
                  (merge
                    (select-keys info [:fixed-arity :variadic?])
                    (select-keys (-> vexpr :methods first) [:tag]))))))
          (when-not texpr
            (throw
              (error
                env
                "set! target must be a field or a symbol naming a var")))
          (cond
            (and
              (not (:def-emits-var env))
              (some?
                ((quote
                   #{*warn-on-infer*
                     *unchecked-arrays*
                     *unchecked-if*})
                  target))) {:env env  :op :no-op}
            :else {:env env 
                   :op :set! 
                   :form form 
                   :target texpr 
                   :val vexpr 
                   :children [:target :val]}))))))
(defn- analyze-js-star-args [js-op env args]
  (first
    (reduce
      (fn [[argexprs env] arg] [(conj argexprs (analyze env arg))
                                (if
                                  (= js-op (quote cljs.core/and))
                                  (set-test-induced-tags env arg)
                                  env)])
      [[] env]
      args)))
(defn- core-ns? [ns-sym]
  (let [s (name ns-sym)]
    (and
      (not= (quote cljs.user) ns-sym)
      (or
        (string/starts-with? s "cljs.")
        (string/starts-with? s "clojure.")))))
(defn cacheable-files
  ([rsrc ext] (cacheable-files rsrc ext nil))
  ([rsrc ext opts]
    (let [{:keys [ns]} (parse-ns rsrc)
          path (cache-base-path (util/path rsrc) opts)
          name (util/ns->relpath ns nil File/separatorChar)]
      (into
        {}
        (map
          (fn [[k v]] [k
                       (io/file
                         path
                         (if (and
                               (=
                                 (str
                                   "cljs"
                                   File/separatorChar
                                   "core$macros")
                                 name)
                               (= :source k))
                           (str "cljs" File/separatorChar "core.cljc")
                           (str name v)))]))
        {:source (str "." ext) 
         :output-file ".js" 
         :source-map ".js.map" 
         :analysis-cache-edn (str "." ext ".cache.edn") 
         :analysis-cache-json (str "." ext ".cache.json")}))))
(defmethod
  parse
  (quote ns*)
  [_ env [_ quoted-specs :as form] _ opts]
  (when-let [not-quoted (->>
                          (remove keyword? quoted-specs)
                          (remove
                            (fn*
                              [p1__3951#]
                              (and
                                (seq? p1__3951#)
                                (= (quote quote) (first p1__3951#)))))
                          first)]
    (throw
      (error
        env
        (str
          "Arguments to "
          (name (first quoted-specs))
          " must be quoted. Offending spec: "
          not-quoted))))
  (when-not *allow-ns*
    (throw
      (error
        env
        (str
          "Calls to `"
          (name (first quoted-specs))
          "` must appear at the top-level."))))
  (let [specs (if (= :import (first quoted-specs))
                (canonicalize-import-specs quoted-specs)
                (canonicalize-specs quoted-specs))
        name (-> env :ns :name)
        args (desugar-ns-specs (list (process-rewrite-form specs)))
        {:keys [as-aliases]  args :libspecs} (nses/elide-aliases-from-ns-specs
                                               args)
        {excludes :excludes  core-renames :renames} (parse-ns-excludes
                                                      env
                                                      args)
        core-renames (reduce
                       (fn [m [original renamed]]
                         (assoc
                           m
                           renamed
                           (symbol "cljs.core" (str original))))
                       {}
                       core-renames)
        deps (atom [])
        aliases (atom {:fns as-aliases  :macros as-aliases})
        spec-parsers {:require
                      (partial
                        parse-require-spec
                        env
                        false
                        deps
                        aliases) 
                      :require-macros
                      (partial
                        parse-require-spec
                        env
                        true
                        deps
                        aliases) 
                      :use
                      (comp
                        (partial
                          parse-require-spec
                          env
                          false
                          deps
                          aliases)
                        (partial use->require env)) 
                      :use-macros
                      (comp
                        (partial
                          parse-require-spec
                          env
                          true
                          deps
                          aliases)
                        (partial use->require env)) 
                      :import (partial parse-import-spec env deps)}
        reload (atom
                 {:use nil 
                  :require nil 
                  :use-macros nil 
                  :require-macros nil})
        reloads (atom {})
        {uses :use 
         requires :require 
         renames :rename 
         use-macros :use-macros 
         require-macros :require-macros 
         rename-macros :rename-macros 
         imports :import 
         :as params} (reduce
                       (fn [m [k & libs]]
                         (when-not (= :import k)
                           (when (some? (some #{:reload} libs))
                             (swap! reload assoc k :reload))
                           (when (some? (some #{:reload-all} libs))
                             (swap! reload assoc k :reload-all)))
                         (when-some
                           [xs
                            (seq
                              (filter
                                (fn*
                                  [p1__3952#]
                                  (-> p1__3952# meta :reload))
                                libs))]
                           (swap!
                             reloads
                             assoc
                             k
                             (zipmap
                               (map first xs)
                               (map
                                 (fn*
                                   [p1__3953#]
                                   (-> p1__3953# meta :reload))
                                 xs))))
                         (apply
                           merge-with
                           merge
                           m
                           (map
                             (spec-parsers k)
                             (remove #{:reload :reload-all} libs))))
                       {}
                       (remove (fn [[r]] (= r :refer-clojure)) args))]
    (set! *cljs-ns* name)
    (let [require-info {:rename-macros rename-macros 
                        :renames (merge renames core-renames) 
                        :use-macros use-macros 
                        :excludes excludes 
                        :name name 
                        :imports imports 
                        :requires requires 
                        :uses uses 
                        :require-macros require-macros 
                        :as-aliases as-aliases}]
      (swap!
        env/*compiler*
        update-in
        [:cljs.analyzer/namespaces name]
        merge-ns-info
        require-info
        env)
      (merge
        {:op :ns* 
         :env env 
         :form form 
         :deps (into [] (distinct (clojure.core/deref deps))) 
         :reload (clojure.core/deref reload) 
         :reloads (clojure.core/deref reloads)}
        (cond->
          require-info
          ((clojure.core/deref reload) :use)
          (update-in
            [:uses]
            (fn [m]
              (with-meta m {((clojure.core/deref reload) :use) true})))
          ((clojure.core/deref reload) :require)
          (update-in
            [:requires]
            (fn [m]
              (with-meta
                m
                {((clojure.core/deref reload) :require) true}))))))))
(defmethod
  parse
  (quote ns)
  [_ env [_ name & args :as form] _ opts]
  (when-not *allow-ns*
    (throw
      (error
        env
        "Namespace declarations must appear at the top-level.")))
  (when-not (symbol? name)
    (throw (error env "Namespaces must be named by a symbol.")))
  (let [name (cond-> name (:macros-ns opts) macro-ns-name)]
    (let [segments (string/split (clojure.core/name name) #"\.")]
      (when (= 1 (count segments))
        (warning :single-segment-namespace env {:name name}))
      (let [segment (some js-reserved segments)]
        (when (some? segment)
          (warning :munged-namespace env {:name name})))
      (find-def-clash env name segments)
      (when (some (complement util/valid-js-id-start?) segments)
        (throw
          (AssertionError.
            (str
              "Namespace "
              name
              " has a segment starting with an invaild "
              "JavaScript identifier")))))
    (let [docstring (when (string? (first args)) (first args))
          mdocstr (-> name meta :doc)
          args (if (some? docstring) (next args) args)
          metadata (when (map? (first args)) (first args))
          args (desugar-ns-specs
                 (rewrite-cljs-aliases (if metadata (next args) args)))
          {:keys [as-aliases]  args :libspecs} (nses/elide-aliases-from-ns-specs
                                                 args)
          name (vary-meta name merge metadata)
          {excludes :excludes  core-renames :renames} (parse-ns-excludes
                                                        env
                                                        args)
          core-renames (reduce
                         (fn [m [original renamed]]
                           (assoc
                             m
                             renamed
                             (symbol "cljs.core" (str original))))
                         {}
                         core-renames)
          deps (atom [])
          aliases (atom {:fns as-aliases  :macros as-aliases})
          spec-parsers {:require
                        (partial
                          parse-require-spec
                          env
                          false
                          deps
                          aliases) 
                        :require-macros
                        (partial
                          parse-require-spec
                          env
                          true
                          deps
                          aliases) 
                        :use
                        (comp
                          (partial
                            parse-require-spec
                            env
                            false
                            deps
                            aliases)
                          (partial use->require env)) 
                        :use-macros
                        (comp
                          (partial
                            parse-require-spec
                            env
                            true
                            deps
                            aliases)
                          (partial use->require env)) 
                        :import (partial parse-import-spec env deps)}
          valid-forms (atom
                        #{:use-macros
                          :use
                          :require
                          :require-macros
                          :import})
          reload (atom
                   {:use nil 
                    :require nil 
                    :use-macros nil 
                    :require-macros nil})
          reloads (atom {})
          {uses :use 
           requires :require 
           renames :rename 
           use-macros :use-macros 
           require-macros :require-macros 
           rename-macros :rename-macros 
           imports :import 
           :as params} (reduce
                         (fn [m [k & libs :as libspec]]
                           (when-not (#{:use-macros
                                        :use
                                        :require
                                        :require-macros
                                        :import}
                                       k)
                             (throw
                               (error
                                 env
                                 (str
                                   "Only :refer-clojure, :require, :require-macros, :use, :use-macros, and :import libspecs supported. Got "
                                   libspec
                                   " instead."))))
                           (when-not ((clojure.core/deref valid-forms)
                                       k)
                             (throw
                               (error
                                 env
                                 (str
                                   "Only one "
                                   k
                                   " form is allowed per namespace definition"))))
                           (swap! valid-forms disj k)
                           (when-not (= :import k)
                             (when (some? (some #{:reload} libs))
                               (swap! reload assoc k :reload))
                             (when (some? (some #{:reload-all} libs))
                               (swap! reload assoc k :reload-all)))
                           (when-let [xs
                                      (seq
                                        (filter
                                          (fn*
                                            [p1__3908#]
                                            (->
                                             p1__3908#
                                             meta
                                             :reload))
                                          libs))]
                             (swap!
                               reloads
                               assoc
                               k
                               (zipmap
                                 (map first xs)
                                 (map
                                   (fn*
                                     [p1__3909#]
                                     (-> p1__3909# meta :reload))
                                   xs))))
                           (apply
                             merge-with
                             merge
                             m
                             (map
                               (spec-parsers k)
                               (remove #{:reload :reload-all} libs))))
                         {}
                         (remove
                           (fn [[r]] (= r :refer-clojure))
                           args))]
      (set! *cljs-ns* name)
      (let [ns-info {:rename-macros rename-macros 
                     :renames (merge renames core-renames) 
                     :use-macros use-macros 
                     :excludes excludes 
                     :name name 
                     :imports imports 
                     :requires requires 
                     :uses uses 
                     :require-macros require-macros 
                     :doc (or docstring mdocstr) 
                     :as-aliases as-aliases}]
        (swap!
          env/*compiler*
          update-in
          [:cljs.analyzer/namespaces name]
          merge
          ns-info)
        (merge
          {:op :ns 
           :env env 
           :form form 
           :deps (into [] (distinct (clojure.core/deref deps))) 
           :reload (clojure.core/deref reload) 
           :reloads (clojure.core/deref reloads)}
          (cond->
            ns-info
            ((clojure.core/deref reload) :use)
            (update-in
              [:uses]
              (fn [m]
                (with-meta
                  m
                  {((clojure.core/deref reload) :use) true})))
            ((clojure.core/deref reload) :require)
            (update-in
              [:requires]
              (fn [m]
                (with-meta
                  m
                  {((clojure.core/deref reload) :require) true})))))))))
(defn ns-side-effects [env {:keys [op]  :as ast} opts]
  (if (#{:ns* :ns} op)
    (let [{:keys
           [name deps uses require-macros use-macros reload reloads]} ast]
      (when (and *analyze-deps* (seq deps))
        (analyze-deps
          (if (repl-self-require? env deps) (quote cljs.user) name)
          deps
          env
          (dissoc opts :macros-ns)))
      (if *load-macros*
        (do
          (load-core)
          (doseq [nsym (vals use-macros)]
            (let [k (or
                      (:use-macros reload)
                      (get-in reloads [:use-macros nsym])
                      (and (= nsym name) *reload-macros* :reload))]
              (if k
                (locking load-mutex (clojure.core/require nsym k))
                (locking load-mutex (clojure.core/require nsym)))
              (intern-macros nsym k)))
          (doseq [nsym (vals require-macros)]
            (let [k (or
                      (:require-macros reload)
                      (get-in reloads [:require-macros nsym])
                      (and (= nsym name) *reload-macros* :reload))]
              (if k
                (locking load-mutex (clojure.core/require nsym k))
                (locking load-mutex (clojure.core/require nsym)))
              (intern-macros nsym k)))
          (-> ast
           (check-use-macros-inferring-missing env)
           (check-rename-macros-inferring-missing env)))
        (do
          (check-uses
            (when (and *analyze-deps* (seq uses))
              (missing-uses uses env))
            env)
          ast)))
    ast))
(defmethod
  error-message
  :protocol-with-overwriting-method
  [warning-type info]
  (let [overwritten-protocol (-> info :existing :protocol)]
    (str
      "Protocol "
      (:protocol info)
      " is overwriting "
      (if overwritten-protocol "method" "function")
      " "
      (:name info)
      (when overwritten-protocol
        (str " of protocol " (name overwritten-protocol))))))
(defmethod
  parse
  (quote recur)
  [op env [_ & exprs :as form] _ _]
  (let [context (:context env)
        frame (first *recur-frames*)
        add-implicit-target-object? (and
                                      (:protocol-impl frame)
                                      (=
                                        (count exprs)
                                        (dec (count (:params frame)))))
        exprs (cond->> exprs add-implicit-target-object? (cons nil))
        exprs (disallowing-recur
                (vec
                  (map
                    (fn*
                      [p1__3518#]
                      (analyze (assoc env :context :expr) p1__3518#))
                    exprs)))]
    (when-not frame (throw (error env "Can't recur here")))
    (when-not (= (count exprs) (count (:params frame)))
      (throw
        (error
          env
          (str
            "recur argument count mismatch, expected: "
            (count (:params frame))
            " args, got: "
            (count exprs)))))
    (when (and
            (:protocol-impl frame)
            (not add-implicit-target-object?))
      (warning
        :protocol-impl-recur-with-target
        env
        {:form (:form (first exprs))}))
    (reset! (:flag frame) true)
    (swap!
      (:tags frame)
      (fn [tags]
        (mapv
          (fn [tag expr]
            (if (= :loop (:local expr))
              (quote any)
              (add-types tag (:tag expr))))
          tags
          exprs)))
    (assoc
      {:env env  :op :recur  :form form}
      :frame
      frame
      :exprs
      exprs
      :children
      [:exprs])))
(defn analyze-deps
  "Given a lib, a namespace, deps, its dependencies, env, an analysis environment\n   and opts, compiler options - analyze all of the dependencies. Required to\n   correctly analyze usage of other namespaces."
  ([lib deps env]
    (analyze-deps
      lib
      deps
      env
      (when env/*compiler*
        (:options (clojure.core/deref env/*compiler*)))))
  ([lib deps env opts]
    (let [compiler (clojure.core/deref env/*compiler*)]
      (binding [*cljs-dep-set* (vary-meta
                                 (conj *cljs-dep-set* lib)
                                 update-in
                                 [:dep-path]
                                 conj
                                 lib)]
        (assert
          (every?
            (fn*
              [p1__3608#]
              (not (contains? *cljs-dep-set* p1__3608#)))
            deps)
          (str
            "Circular dependency detected, "
            (apply
              str
              (interpose
                " -> "
                (conj
                  (-> *cljs-dep-set* meta :dep-path)
                  (some *cljs-dep-set* deps))))))
        (doseq [dep deps]
          (when-not (or
                      (some?
                        (get-in
                          compiler
                          [:cljs.analyzer/namespaces dep :defs]))
                      (node-module-dep? dep)
                      (js-module-exists? (name dep))
                      (deps/find-classpath-lib dep))
            (let [idx (:js-dependency-index compiler)
                  dep (-> dep lib&sublib first)]
              (if (contains? idx (name dep))
                (let [dep-name (name dep)]
                  (when (string/starts-with? dep-name "goog.")
                    (let [js-lib (get idx dep-name)
                          ns (externs/analyze-goog-file
                               (:file js-lib)
                               (symbol dep-name))]
                      (swap!
                        env/*compiler*
                        update-in
                        [:cljs.analyzer/namespaces dep]
                        merge
                        ns))))
                (if-some
                  [src (locate-src dep)]
                  (analyze-file src opts)
                  (throw
                    (error
                      env
                      (error-message
                        :undeclared-ns
                        {:ns-sym dep 
                         :js-provide (name dep)}))))))))))))
(defn macroexpand-1
  "Given a env, an analysis environment, and form, a ClojureScript form,\n   macroexpand the form once."
  [env form]
  (wrapping-errors env (macroexpand-1* env form)))
(defn get-expander* [sym env]
  (when-not (or
              (some? (gets env :locals sym))
              (and (excluded? env sym) (not (used? env sym))))
    (let [nstr (namespace sym)]
      (cond
        (some? nstr) (let [ns (get-expander-ns env nstr)]
                       (when (some? ns)
                         (.findInternedVar ns (symbol (name sym)))))
        (some? (gets env :ns :rename-macros sym)) (let 
                                                    [qualified-symbol
                                                     (gets
                                                       env
                                                       :ns
                                                       :rename-macros
                                                       sym)
                                                     nsym
                                                     (symbol
                                                       (namespace
                                                         qualified-symbol))
                                                     sym
                                                     (symbol
                                                       (name
                                                         qualified-symbol))]
                                                    (.findInternedVar
                                                      (find-ns nsym)
                                                      sym))
        :else (let [nsym (gets env :ns :use-macros sym)]
                (if (and (some? nsym) (symbol? nsym))
                  (.findInternedVar (find-ns nsym) sym)
                  (.findInternedVar
                    (find-ns (quote cljs.core))
                    sym)))))))
(defn cache-file
  "Given a ClojureScript source file returns the read/write path to the analysis\n      cache file. Defaults to the read path which is usually also the write path."
  ([src] (cache-file src "out"))
  ([src output-dir] (cache-file src (parse-ns src) output-dir))
  ([src ns-info output-dir]
    (cache-file src ns-info output-dir :read nil))
  ([src ns-info output-dir mode]
    (cache-file src ns-info output-dir mode nil))
  ([src ns-info output-dir mode opts]
    {:pre [(map? ns-info)]}
    (let [ext (cache-analysis-ext)]
      (if-let [core-cache (and
                            (= mode :read)
                            (= (:ns ns-info) (quote cljs.core))
                            (io/resource
                              (str "cljs/core.cljs.cache.aot." ext)))]
        core-cache
        (let [aot-cache-file (when (util/url? src)
                               ((keyword (str "analysis-cache-" ext))
                                 (cacheable-files
                                   src
                                   (util/ext src)
                                   opts)))]
          (if (and aot-cache-file (.exists aot-cache-file))
            aot-cache-file
            (let [target-file (util/to-target-file
                                output-dir
                                ns-info
                                (util/ext (:source-file ns-info)))]
              (io/file (str target-file ".cache." ext)))))))))
(defn load-core []
  (when (not (clojure.core/deref -cljs-macros-loaded))
    (reset! -cljs-macros-loaded true)
    (if *cljs-macros-is-classpath*
      (locking load-mutex (load *cljs-macros-path*))
      (locking load-mutex (load-file *cljs-macros-path*))))
  (intern-macros (quote cljs.core)))
(defn cache-base-path
  ([path] (cache-base-path path nil))
  ([path opts]
    (io/file
      (System/getProperty "user.home")
      ".cljs"
      ".aot_cache"
      (util/clojurescript-version)
      (build-affecting-options-sha path opts))))
(defmethod
  parse
  (quote throw)
  [op env [_ throw-form :as form] name _]
  (cond
    (= 1 (count form)) (throw
                         (error
                           env
                           "Too few arguments to throw, throw expects a single Error instance"))
    (< 2 (count form)) (throw
                         (error
                           env
                           "Too many arguments to throw, throw expects a single Error instance")))
  (let [throw-expr (disallowing-recur
                     (analyze (assoc env :context :expr) throw-form))]
    {:env env 
     :op :throw 
     :form form 
     :exception throw-expr 
     :children [:exception]}))
(defn write-analysis-cache
  ([ns cache-file] (write-analysis-cache ns cache-file nil))
  ([ns cache-file src]
    (util/mkdirs cache-file)
    (dump-specs ns)
    (let [ext (util/ext cache-file)
          analysis (dissoc
                     (get-in
                       (clojure.core/deref env/*compiler*)
                       [:cljs.analyzer/namespaces ns])
                     :macros)]
      (case
        ext
        "edn"
        (spit
          cache-file
          (str
            ";; Analyzed by ClojureScript "
            (util/clojurescript-version)
            "\n"
            (pr-str analysis)))
        "json"
        (when-let [{:keys [writer write]} (clojure.core/deref transit)]
          (with-open [os (io/output-stream cache-file)]
            (write (writer os :json transit-write-opts) analysis)))))
    (when src (.setLastModified cache-file (util/last-modified src)))))
(defn- do-macroexpand-check [env form mac-var]
  (when (not
          (-> (clojure.core/deref env/*compiler*)
           :options
           :spec-skip-macros))
    (let [mchk (some->
                 (find-ns (quote clojure.spec.alpha))
                 (ns-resolve (quote macroexpand-check)))]
      (when (some? mchk)
        (try
          (mchk mac-var (next form))
          (catch
            Throwable
            e
            (throw
              (ex-info
                nil
                (error-data env :macro-syntax-check (var->sym mac-var))
                e))))))))
(defn resolve-alias
  "Takes a namespace and an unqualified symbol and potentially returns a new\n  symbol to be used in lieu of the original."
  [ns sym]
  (if (and
        (= (quote cljs.core) ns)
        ((quote #{aget aset}) sym)
        (checked-arrays))
    (get-in
      (quote
        {:warn {aget checked-aget  aset checked-aset} 
         :error {aget checked-aget'  aset checked-aset'}})
      [(checked-arrays) sym])
    sym))
(defmethod
  error-message
  :invalid-array-access
  [warning-type {:keys [name types]}]
  (case
    name
    (cljs.core/checked-aget cljs.core/checked-aget')
    (str
      "cljs.core/aget, arguments must be an array followed by numeric indices, got "
      types
      " instead"
      (when (or
              (= (quote object) (first types))
              (every? #{(quote string)} (rest types)))
        (str
          " (consider "
          (if (== 2 (count types))
            "goog.object/get"
            "goog.object/getValueByKeys")
          " for object access)")))
    (cljs.core/checked-aset cljs.core/checked-aset')
    (str
      "cljs.core/aset, arguments must be an array, followed by numeric indices, followed by a value, got "
      types
      " instead"
      (when (or
              (= (quote object) (first types))
              (every? #{(quote string)} (butlast (rest types))))
        " (consider goog.object/set for object access)"))))
(defn find-def-clash [env ns segments]
  (let [to-check (map
                   (fn [xs] [(symbol (string/join "." (butlast xs)))
                             (symbol (last xs))])
                   (drop 2 (reductions conj [] segments)))]
    (doseq [[clash-ns name] to-check]
      (when (get-in
              (clojure.core/deref env/*compiler*)
              [:cljs.analyzer/namespaces clash-ns :defs name])
        (warning
          :ns-var-clash
          env
          {:ns ns  :var (symbol (str clash-ns) (str name))})))))
(defn confirm-bindings
  "Given env, an analysis environment env, and names, a list of symbols, confirm\n   that all correspond to declared dynamic vars."
  [env names]
  (doseq [name names]
    (let [env (assoc env :ns (get-namespace *cljs-ns*))
          ev (resolve-existing-var env name)]
      (when (and ev (not (-> ev :dynamic)))
        (warning :dynamic env {:ev ev  :name (:name ev)})))))
(defn array-type? [t]
  (cond
    (nil? t) true
    (= (quote clj-nil) t) true
    (js-tag? t) true
    (= (quote any) t) true
    (contains? array-types t) true
    :else (boolean
            (when (set? t)
              (or
                (contains? t (quote any))
                (contains? t (quote js))
                (some array-types t))))))
(defn resolve-macro-ns-alias
  ([env name] (resolve-macro-ns-alias env name (symbol name)))
  ([env name not-found]
    (let [sym (symbol name)]
      (get (:require-macros (:ns env)) sym not-found))))
(defn confirm-ns
  "Given env, an analysis environment, and ns-sym, a symbol identifying a\n   namespace, confirm that the namespace exists. Warn if not found."
  [env ns-sym]
  (when (and
          (not= (quote cljs.core) ns-sym)
          (nil? (get implicit-nses ns-sym))
          (nil? (get (-> env :ns :requires) ns-sym))
          (nil?
            (gets
              (clojure.core/deref env/*compiler*)
              :cljs.analyzer/namespaces
              ns-sym))
          (nil? (util/ns->source ns-sym))
          (not (js-module-exists? ns-sym)))
    (warning :undeclared-ns env {:ns-sym ns-sym  :js-provide ns-sym})))
(defn- load-data-reader-file [mappings url]
  (with-open [rdr (readers/input-stream-push-back-reader
                    (.openStream url))]
    (binding [*file* (.getFile url)]
      (let [new-mappings (reader/read
                           {:eof nil 
                            :read-cond :allow 
                            :features #{:cljs}}
                           rdr)]
        (when (not (map? new-mappings))
          (throw
            (ex-info
              (str "Not a valid data-reader map")
              {:url url  :clojure.error/phase :compilation})))
        (reduce
          (fn [m [k v]]
            (when (not (symbol? k))
              (throw
                (ex-info
                  (str "Invalid form in data-reader file")
                  {:url url 
                   :form k 
                   :clojure.error/phase :compilation})))
            (when (and (contains? mappings k) (not= (mappings k) v))
              (throw
                (ex-info
                  "Conflicting data-reader mapping"
                  {:url url 
                   :conflict k 
                   :mappings m 
                   :clojure.error/phase :compilation})))
            (assoc m k v))
          mappings
          new-mappings)))))
(defn check-use-macros
  ([use-macros env] (check-use-macros use-macros nil env))
  ([use-macros missing-uses env]
    (let [cenv (clojure.core/deref env/*compiler*)]
      (doseq [[sym lib] use-macros]
        (when (missing-use-macro? lib sym)
          (throw
            (error
              env
              (error-message
                :undeclared-ns-form
                {:type "macro"  :lib lib  :sym sym})))))
      (check-uses (missing-use-macros missing-uses env) env)
      (inferred-use-macros missing-uses env))))
(defn- build-method-call
  "Builds the intermediate method call map used to reason about the parsed form during\n  compilation."
  [target meth args]
  (if (symbol? meth)
    {:dot-action :cljs.analyzer/call 
     :target target 
     :method meth 
     :args args}
    {:dot-action :cljs.analyzer/call 
     :target target 
     :method (first meth) 
     :args args}))
(defn constant-value? [{:keys [op]  :as ast}]
  (or
    (#{:const :quote} op)
    (and
      (#{:vector :set :map} op)
      (every? constant-value? (ast-children ast)))))
(defn add-types
  "Produces a union of types."
  ([] (quote any))
  ([t1] t1)
  ([t1 t2]
    (if (or (nil? t1) (nil? t2))
      (quote any)
      (-> (set/union (->type-set t1) (->type-set t2))
       canonicalize-type)))
  ([t1 t2 & ts] (apply add-types (add-types t1 t2) ts)))
(defn- repl-self-require? [env deps]
  (and (:repl-env env) (some #{*cljs-ns*} deps)))
(defn confirm-var-exists-throw []
  (fn [env prefix suffix]
    (confirm-var-exists
      env
      prefix
      suffix
      (fn [env prefix suffix]
        (throw
          (error
            env
            (str
              "Unable to resolve var: "
              suffix
              " in this context")))))))
(defn resolve-macro-var
  "Given env, an analysis environment, and sym, a symbol, resolve a macro."
  [env sym]
  (let [ns (-> env :ns :name)
        namespaces (get
                     (clojure.core/deref env/*compiler*)
                     :cljs.analyzer/namespaces)]
    (cond
      (some? (namespace sym)) (let [ns (namespace sym)
                                    ns
                                    (if
                                      (= "clojure.core" ns)
                                      "cljs.core"
                                      ns)
                                    full-ns
                                    (resolve-macro-ns-alias env ns)]
                                (get-in
                                  namespaces
                                  [full-ns
                                   :macros
                                   (symbol (name sym))]))
      (some? (get-in namespaces [ns :use-macros sym])) (let 
                                                         [full-ns
                                                          (get-in
                                                            namespaces
                                                            [ns
                                                             :use-macros
                                                             sym])]
                                                         (get-in
                                                           namespaces
                                                           [full-ns
                                                            :macros
                                                            sym]))
      (some? (get-in namespaces [ns :rename-macros sym])) (let 
                                                            [qualified-symbol
                                                             (get-in
                                                               namespaces
                                                               [ns
                                                                :rename-macros
                                                                sym])
                                                             full-ns
                                                             (symbol
                                                               (namespace
                                                                 qualified-symbol))
                                                             sym
                                                             (symbol
                                                               (name
                                                                 qualified-symbol))]
                                                            (get-in
                                                              namespaces
                                                              [full-ns
                                                               :macros
                                                               sym]))
      :else (let [ns (cond
                       (some? (get-in namespaces [ns :macros sym])) ns
                       (core-name? env sym) (quote cljs.core))]
              (when (some? ns) (get-in namespaces [ns :macros sym]))))))
(defmethod
  resolve*
  :node
  [env sym full-ns current-ns]
  (if (node-like?)
    (let [pre (extern-pre sym current-ns)]
      {:ns current-ns 
       :name
       (symbol
         (str current-ns)
         (str (munge-node-lib full-ns) "." (name sym))) 
       :op :js-var 
       :tag (with-meta (quote js) {:prefix pre}) 
       :foreign true})
    {:ns current-ns 
     :name
     (symbol
       (str current-ns)
       (str (munge-node-lib full-ns) "." (name sym))) 
     :op :js-var 
     :foreign true}))
(defn check-uses [uses env]
  (let [cenv (clojure.core/deref env/*compiler*)]
    (doseq [[sym lib] uses]
      (when (missing-use? lib sym cenv)
        (throw
          (error
            env
            (error-message
              :undeclared-ns-form
              {:type "var"  :lib lib  :sym sym})))))))
(defn dump-specs
  "Dumps registered speced vars for a given namespace into the compiler\n  environment."
  [ns]
  (let [spec-vars (get-spec-vars) ns-str (str ns)]
    (swap!
      env/*compiler*
      update-in
      [:cljs.analyzer/namespaces ns]
      merge
      (when-let [registry-ref (:registry-ref spec-vars)]
        {:cljs.spec/registry-ref(
                    into[
                      ](
                      filter( fn[ [k_ ]]( =ns-str(namespacek)) ))(clojure.core/deref       (clojure.core/deref
                        registry-ref)))})(when-let[speced-vars      (:speced-varsspec-vars )]{:cljs.spec/speced-vars
        (into[](filter(fn[v](or(
                    =ns-str                     (namespace               v))(=ns
                        (-> vmeta                         :fdef-ns                        )) )))(clojure.core/deref                            (clojure.core/derefspeced-vars
                      )))}))))
(defn- get-spec-vars []
  (when-let [spec-ns (find-ns (quote cljs.spec.alpha))]
    (locking load-mutex
     {:registry-ref (ns-resolve spec-ns (quote registry-ref)) 
      :speced-vars (ns-resolve spec-ns (quote _speced_vars))})))
(defn get-bridged-alias-map
  "Returns clojure.tools.reader/*alias-map* for bridging"
  []
  (try
    (clojure.core/deref
      (ns-resolve (quote clojure.tools.reader) (quote *alias-map*)))
    (catch Throwable t nil)))
(defmethod
  error-message
  :fn-deprecated
  [warning-type info]
  (str (-> info :fexpr :info :name) " is deprecated"))
(defmethod
  error-message
  :unsupported-preprocess-value
  [warning-type {:keys [preprocess file]}]
  (str
    "Unsupported preprocess value "
    preprocess
    " for foreign library "
    file
    "."))
(defmethod
  error-message
  :invalid-protocol-symbol
  [warning-type info]
  (str "Symbol " (:protocol info) " is not a protocol"))
(defmethod
  build-dot-form
  [:cljs.analyzer/expr :cljs.analyzer/property :cljs.analyzer/list]
  [[target prop args]]
  (throw
    (Error.
      (str
        "Cannot provide arguments "
        args
        " on property access "
        prop))))
(defmethod
  error-message
  :invoke-ctor
  [warning-type info]
  (str
    "Cannot invoke type constructor "
    (-> info :fexpr :info :name)
    " as function "))
(defmethod
  error-message
  :undeclared-protocol-symbol
  [warning-type info]
  (str "Can't resolve protocol symbol " (:protocol info)))
(defmethod
  error-message
  :dynamic
  [warning-type info]
  (str (:name info) " not declared ^:dynamic"))
(defmethod
  error-message
  :extend-type-invalid-method-shape
  [warning-type {:keys [protocol method]  :as info}]
  (str
    "Bad extend-type method shape for protocol "
    protocol
    " method "
    method
    ", method arities must be grouped together"))
(defmethod
  error-message
  :ns-var-clash
  [warning-type {:keys [ns var]  :as info}]
  (str "Namespace " ns " clashes with var " var))
(defmethod
  error-message
  :protocol-deprecated
  [warning-type info]
  (str "Protocol " (:protocol info) " is deprecated"))
(defmethod
  error-message
  :protocol-multiple-impls
  [warning-type info]
  (str "Protocol " (:protocol info) " implemented multiple times"))
(defmethod
  error-message
  :unsupported-js-module-type
  [warning-type {:keys [module-type file]  :as info}]
  (str
    "Unsupported JavaScript module type "
    module-type
    " for foreign library "
    file
    "."))
(defn js-star-interp [env s]
  (let [idx (.indexOf s "~{")]
    (if (== -1 idx)
      (list s)
      (let [end (.indexOf s "}" idx)
            inner (:name
                    (resolve-existing-var
                      env
                      (symbol (subs s (+ 2 idx) end))))]
        (lazy-seq
          (cons
            (subs s 0 idx)
            (cons inner (js-star-interp env (subs s (inc end))))))))))
(defmethod
  error-message
  :protocol-impl-recur-with-target
  [warning-type info]
  (str
    "Ignoring target object \""
    (pr-str (:form info))
    "\" passed in recur to protocol method head"))
(defmethod
  error-message
  :unprovided
  [warning-type info]
  (str
    "Required namespace not provided for "
    (string/join " " (:unprovided info))))
(defmethod
  error-message
  :preamble-missing
  [warning-type info]
  (str
    "Preamble resource file not found: "
    (string/join " " (:missing info))))
(defn requires-analysis?
  "Given a src, a resource, and output-dir, a compilation output directory\n      return true or false depending on whether src needs to be (re-)analyzed.\n      Can optionally pass cache, the analysis cache file."
  ([src] (requires-analysis? src "out"))
  ([src output-dir]
    (let [cache (cache-file src output-dir)]
      (requires-analysis? src cache output-dir nil)))
  ([src cache output-dir]
    (requires-analysis? src cache output-dir nil))
  ([src cache output-dir opts]
    (cond
      (util/url? cache) (let [path (.getPath cache)]
                          (if (or
                                (.endsWith
                                  path
                                  "cljs/core.cljs.cache.aot.edn")
                                (.endsWith
                                  path
                                  "cljs/core.cljs.cache.aot.json"))
                            false
                            (throw
                              (Exception.
                                (str
                                  "Invalid anlaysis cache, must be file not URL "
                                  cache)))))
      (and (util/file? cache) (not (.exists cache))) true
      :else (let [out-src (util/to-target-file
                            output-dir
                            (parse-ns src))
                  cache-src (:output-file
                              (cacheable-files
                                src
                                (util/ext src)
                                opts))]
              (if (and
                    (not (.exists out-src))
                    (not (.exists cache-src)))
                true
                (or (not cache) (util/changed? src cache)))))))
(defmethod
  error-message
  :protocol-duped-method
  [warning-type info]
  (str
    "Duplicated methods in protocol implementation "
    (:protocol info)
    " "
    (:fname info)))
(defmethod
  error-message
  :extending-base-js-type
  [warning-type info]
  (str
    "Extending an existing JavaScript type - use a different symbol name "
    "instead of "
    (:current-symbol info)
    " e.g "
    (:suggested-symbol info)))
(defmethod
  build-dot-form
  :default
  [dot-form]
  (throw
    (Error.
      (str
        "Unknown dot form of "
        (list* (quote .) dot-form)
        " with classification "
        (classify-dot-form dot-form)))))
(defmethod
  error-message
  :protocol-impl-with-variadic-method
  [warning-type info]
  (str
    "Protocol "
    (:protocol info)
    " implements method "
    (:name info)
    " with variadic signature (&)"))
(defmethod
  error-message
  :redef-in-file
  [warning-type info]
  (str (:sym info) " at line " (:line info) " is being replaced"))
(defmethod
  error-message
  :protocol-with-variadic-method
  [warning-type info]
  (str
    "Protocol "
    (:protocol info)
    " declares method "
    (:name info)
    " with variadic signature (&)"))
(defmethod
  error-message
  :undeclared-macros-ns
  [warning-type {:keys [ns-sym js-provide]  :as info}]
  (str
    "No such macros namespace: "
    ns-sym
    ", could not locate "
    (ns->relpath ns-sym :clj)
    " or "
    (ns->relpath ns-sym :cljc)))
(defmethod
  error-message
  :undeclared-ns-form
  [warning-type info]
  (str
    "Invalid :refer, "
    (:type info)
    " "
    (:lib info)
    "/"
    (:sym info)
    " does not exist"))
(defmethod
  error-message
  :fn-var
  [warning-type info]
  (str
    (symbol (str (:ns-name info)) (str (:sym info)))
    " no longer fn, references are stale"))
(defn locate-src
  "Given a namespace return the corresponding ClojureScript (.cljs or .cljc)\n     resource on the classpath or file from the root of the build."
  [ns]
  (or
    (util/ns->source ns)
    (some
      (fn [source] (if (= ns (:ns source)) (:source-file source)))
      (:sources (clojure.core/deref env/*compiler*)))
    (let [rootp (when-let [root (:root
                                  (clojure.core/deref env/*compiler*))]
                  (.getPath root))
          cljsf (io/file rootp (ns->relpath ns :cljs))
          cljcf (io/file rootp (ns->relpath ns :cljc))]
      (if (and (.exists cljsf) (.isFile cljsf))
        cljsf
        (if (and (.exists cljcf) (.isFile cljcf)) cljcf)))))
(defmethod
  error-message
  :undeclared-ns
  [warning-type {:keys [ns-sym js-provide]  :as info}]
  (str
    "No such namespace: "
    ns-sym
    ", could not locate "
    (ns->relpath ns-sym :cljs)
    ", "
    (ns->relpath ns-sym :cljc)
    ", or JavaScript source providing \""
    js-provide
    "\""
    (when (string/includes? (ns->relpath ns-sym) "_")
      " (Please check that namespaces with dashes use underscores in the ClojureScript file name)")))
(defmethod
  error-message
  :protocol-invalid-method
  [warning-type info]
  (if (:no-such-method info)
    (str
      "Bad method signature in protocol implementation, "
      (:protocol info)
      " does not declare method called "
      (:fname info))
    (str
      "Bad method signature in protocol implementation, "
      (:protocol info)
      " "
      (:fname info)
      " does not declare arity "
      (:invalid-arity info))))
(defmethod
  error-message
  :redef
  [warning-type info]
  (str
    (:sym info)
    " already refers to: "
    (symbol (str (:ns info)) (str (:sym info)))
    " being replaced by: "
    (symbol (str (:ns-name info)) (str (:sym info)))))
(defmethod
  error-message
  :munged-namespace
  [warning-type {:keys [name]  :as info}]
  (let [munged (->>
                 (string/split (clojure.core/name name) #"\.")
                 (map
                   (fn*
                     [p1__2757#]
                     (if (js-reserved p1__2757#)
                       (str p1__2757# "$")
                       p1__2757#)))
                 (string/join ".")
                 (munge))]
    (str
      "Namespace "
      name
      " contains a reserved JavaScript keyword,"
      " the corresponding Google Closure namespace will be munged to "
      munged)))
(defn ast-children [ast]
  (mapcat
    (fn [c] (let [g (get ast c)] (cond (vector? g) g g [g])))
    (:children ast)))
(defn register-specs
  "Registers speced vars found in a namespace analysis cache."
  [cached-ns]
  (try
    (locking load-mutex (clojure.core/require (quote cljs.spec.alpha)))
    (catch Throwable t))
  (let [{:keys [registry-ref speced-vars]} (get-spec-vars)]
    (when-let [registry (seq (:cljs.spec/registry-ref cached-ns))]
      (when registry-ref
        (swap! (clojure.core/deref registry-ref) into registry)))
    (when-let [vars (seq (:cljs.spec/speced-vars cached-ns))]
      (when speced-vars
        (swap! (clojure.core/deref speced-vars) into vars)))))
(defn public-name?
  "Is sym public?"
  [ns sym]
  (let [var-ast (or
                  (gets
                    (clojure.core/deref env/*compiler*)
                    :cljs.analyzer/namespaces
                    ns
                    :defs
                    sym)
                  (gets
                    (clojure.core/deref env/*compiler*)
                    :cljs.analyzer/namespaces
                    ns
                    :macros
                    sym))]
    (and
      (some? var-ast)
      (not (or (:private var-ast) (:anonymous var-ast))))))
(defn macro-ns-name [name]
  (let [name-str (str name)]
    (if-not (.endsWith name-str "$macros")
      (symbol (str name-str "$macros"))
      name)))
(defn analyze-record [env x]
  (let [_items_ (disallowing-recur
                  (analyze (assoc env :context :expr) (into {} x)))
        [ns name] (record-ns+name x)]
    {:op :const 
     :val x 
     :env env 
     :form x 
     :tag (symbol (str ns) (str name))}))
(clojure.core/defn with-core-macros-file
  ([&form &env path & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote do))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/when))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/not=))
                    (clojure.core/list
                      (quote cljs.analyzer/*cljs-macros-path*))
                    (clojure.core/list path))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/reset!))
                    (clojure.core/list
                      (quote cljs.analyzer/-cljs-macros-loaded))
                    (clojure.core/list (quote false))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.analyzer/*cljs-macros-path*))
                      (clojure.core/list path)
                      (clojure.core/list
                        (quote
                          cljs.analyzer/*cljs-macros-is-classpath*))
                      (clojure.core/list (quote false))))))
              body)))))))
(defn elide-env [env ast opts] (dissoc ast :env))
(defn const-expr->constant-value [{:keys [op]  :as e}]
  (case
    op
    :quote
    (const-expr->constant-value (:expr e))
    :const
    (:val e)
    :map
    (zipmap
      (map const-expr->constant-value (:keys e))
      (map const-expr->constant-value (:vals e)))
    :set
    (into #{} (map const-expr->constant-value (:items e)))
    :vector
    (into [] (map const-expr->constant-value (:items e)))))
(defn unchecked-arrays? [] *unchecked-arrays*)
(defn- repeat-char [c n]
  (loop [ret c n n] (if (pos? n) (recur (str ret c) (dec n)) ret)))
(defn resolve-symbol [sym]
  (if (and (not (namespace sym)) (dotted-symbol? sym))
    sym
    (:name
      (binding [*private-var-access-nowarn* true]
        (resolve-var
          (assoc
            (clojure.core/deref env/*compiler*)
            :ns
            (get-namespace *cljs-ns*))
          sym)))))
(clojure.core/defn with-core-macros
  ([&form &env path & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote do))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/when))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/not=))
                    (clojure.core/list
                      (quote cljs.analyzer/*cljs-macros-path*))
                    (clojure.core/list path))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/reset!))
                    (clojure.core/list
                      (quote cljs.analyzer/-cljs-macros-loaded))
                    (clojure.core/list (quote false))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.analyzer/*cljs-macros-path*))
                      (clojure.core/list path)))))
              body)))))))
(defn record-ns+name [x]
  (map
    symbol
    ((juxt
       (comp (fn* [p1__4276#] (string/join "." p1__4276#)) butlast)
       last)
      (string/split (.getName (type x)) #"\."))))
(defn forms-seq
  "DEPRECATED: Seq of Clojure/ClojureScript forms from [f], which can be anything\n     for which `clojure.java.io/reader` can produce a `java.io.Reader`. Optionally\n     accepts a [filename] argument, which the reader will use in any emitted errors."
  ([f] (forms-seq f (source-path f)))
  ([f filename] (forms-seq f filename false))
  ([f filename return-reader?]
    (let [rdr (io/reader f)
          pbr (readers/indexing-push-back-reader
                (PushbackReader. rdr)
                1
                filename)
          data-readers (merge
                         tags/*cljs-data-readers*
                         (load-data-readers))
          forms-seq* (fn forms-seq* []
                       (lazy-seq
                         (let [eof-sentinel (Object.)
                               form (binding 
                                      [*ns* (create-ns *cljs-ns*)
                                       reader/*data-readers*
                                       data-readers
                                       reader/*alias-map*
                                       (apply
                                         merge
                                         ((juxt
                                            :requires
                                            :require-macros)
                                           (get-namespace *cljs-ns*)))]
                                      (reader/read
                                        pbr
                                        nil
                                        eof-sentinel))]
                           (if (identical? form eof-sentinel)
                             (.close rdr)
                             (cons form (forms-seq*))))))]
      (if (true? return-reader?) [(forms-seq*) rdr] (forms-seq*)))))
(defn- compile-syntax-error [env msg symbol]
  (ex-info
    nil
    (error-data env :compile-syntax-check symbol)
    (RuntimeException. msg)))
(defn read-analysis-cache
  ([cache-file src] (read-analysis-cache cache-file src nil))
  ([cache-file src opts]
    (let [{:keys [ns]} (parse-ns
                         src
                         (merge
                           opts
                           {:restore false 
                            :analyze-deps true 
                            :load-macros true}))
          ext (util/ext cache-file)
          cached-ns (case
                      ext
                      "edn"
                      (edn/read-string (slurp cache-file))
                      "json"
                      (let [{:keys [reader read]} (clojure.core/deref
                                                    transit)]
                        (with-open [is (io/input-stream cache-file)]
                          (read
                            (reader is :json transit-read-opts)))))]
      (when (or *verbose* (:verbose opts))
        (util/debug-prn "Reading analysis cache for" (str src)))
      (swap!
        env/*compiler*
        (fn [cenv]
          (do
            (register-specs cached-ns)
            (doseq [x (get-in
                        cached-ns
                        [:cljs.analyzer/constants :order])]
              (register-constant! x))
            (-> cenv
             (assoc-in [:cljs.analyzer/namespaces ns] cached-ns))))))))
cljs.util 598/768 (77.9%)
(defn boolean? [x] (or (true? x) (false? x)))
(defn- main-src-directory []
  (some
    (fn [file] (when (= "main" (.getName file)) file))
    (iterate
      (memfn getParentFile)
      (io/as-file (io/resource "cljs/util.cljc")))))
(defn distinct-by
  ([f coll]
    (let [step (fn step [xs seen]
                 (lazy-seq
                   ((fn [[x :as xs] seen]
                      (when-let [s (seq xs)]
                        (let [v (f x)]
                          (if (contains? seen v)
                            (recur (rest s) seen)
                            (cons x (step (rest s) (conj seen v)))))))
                     xs
                     seen)))]
      (step coll #{}))))
(defn mkdirs
  "Create all parent directories for the passed file."
  [f]
  (.mkdirs (.getParentFile (.getCanonicalFile f))))
(defn ns->relpath
  "Given a namespace as a symbol return the relative path. May optionally\n  provide the file extension, defaults to :cljs."
  ([ns] (ns->relpath ns :cljs))
  ([ns ext] (ns->relpath ns ext \/))
  ([ns ext sep]
    (cond->
      (string/replace (munge-path ns) \. sep)
      ext
      (str "." (name ext)))))
(defn valid-js-id-start? [s] (re-find #"(?U)^[\p{Alpha}_$]" s))
(defn levenshtein-distance
  "The the minimum number of single-element edits needed to\n  transform s in to t."
  [s t]
  (let [f (fn [f s t]
            (cond
              (empty? s) (count t)
              (empty? t) (count s)
              :else (let [cost (if (= (first s) (first t)) 0 1)]
                      (min
                        (inc (f f (rest s) t))
                        (inc (f f s (rest t)))
                        (+ cost (f f (rest s) (rest t)))))))
        g (memoize f)]
    (g g s t)))
(defn suggestion
  "Provides a best suggestion for an unknown, taken from knowns,\n  minimizing the Levenshtein distance, returning nil if threshold\n  cannot be satisfied."
  [threshold unknown knowns]
  (let [distance (partial levenshtein-distance unknown)
        closest (apply min-key distance knowns)
        closest-dist (distance closest)]
    (when (<= closest-dist threshold) closest)))
(defn split-paths [paths-str]
  (string/split paths-str (re-pattern File/pathSeparator)))
(defn file? [f] (instance? File f))
(defn module-file-seq
  "Return a seq of all files in `node_modules` ending in `.js` or `.json` that are\n   not in an internally nested `node_modules` dir."
  ([] (module-file-seq (io/file "node_modules")))
  ([dir]
    (let [fseq (tree-seq
                 (fn [f]
                   (and
                     (. f (isDirectory))
                     (not
                       (boolean
                         (re-find
                           #"node_modules[\\\/].*[\\\/]node_modules"
                           (.getPath f))))))
                 (fn [d] (seq (. d (listFiles))))
                 dir)]
      (filter
        (fn [f]
          (let [path (.getPath f)]
            (or (.endsWith path ".json") (.endsWith path ".js"))))
        fseq))))
(defn filename [f] (.getName f))
(defn to-path
  ([parts] (to-path parts File/separator))
  ([parts sep] (apply str (interpose sep parts))))
(defn url? [f] (instance? URL f))
(defn compiled-by-version [f]
  (with-open [reader (io/reader f)]
    (let [match (some->>
                  reader
                  line-seq
                  first
                  (re-matches #".*ClojureScript (\d+\.\d+\.\d+).*$"))]
      (or (and match (second match)) "0.0.0000"))))
(defn content-sha
  ([s] (content-sha s nil))
  ([s n]
    (let [digest (MessageDigest/getInstance "SHA-1")
          _ (.reset digest)
          _ (.update digest (.getBytes s "utf8"))
          sha (bytes-to-hex-str (.digest digest))]
      (if-not (nil? n) (apply str (take n sha)) sha))))
(defn compilation-error [cause]
  (ex-info nil {:clojure.error/phase:compilation}cause))
(defn- file-hash [file] (if (.isDirectory file) 0 (hash (slurp file))))
(defn build-options [f]
  (with-open [reader (io/reader f)]
    (let [match (some->>
                  reader
                  line-seq
                  first
                  (re-matches #".*ClojureScript \d+\.\d+\.\d+ (.*)$"))]
      (and match (edn/read-string (second match))))))
(defn unknown-opts
  "Takes a set of passed opt keys and known opt keys and for each\n  unknown opt key returns a vector of the key and its (potentially\n  nil) suggestion."
  [passed knowns]
  {:pre [(set? passed) (set? knowns)]}
  (for
    [unknown (set/difference passed knowns)]
    [unknown
     (some->
       (suggestion 3 (str unknown) (map str knowns))
       (subs 1)
       keyword)]))
(defn ns->source
  "Given a namespace as a symbol return the corresponding resource if it exists."
  [ns]
  (or
    (io/resource (ns->relpath ns :cljs))
    (io/resource (ns->relpath ns :cljc))))
(defn output-directory
  ([opts] (output-directory opts "out"))
  ([opts default]
    {:pre [(or (nil? opts) (map? opts))]}
    (or (:output-dir opts) default)))
(defn path-seq [file-str]
  (->>
    File/separator
    java.util.regex.Pattern/quote
    re-pattern
    (string/split file-str)))
(defn changed? [a b] (not (== (last-modified a) (last-modified b))))
(defn munge-path [ss] (clojure.lang.Compiler/munge (str ss)))
(defn debug-prn [& args]
  (binding [*out* *err*]
    (locking debug-prn-mutex (apply println args) (flush))))
(defn- bytes-to-hex-str
  "Convert an array of bytes into a hex encoded string."
  [bytes]
  (loop [index (int 0)
         buffer (StringBuilder. (int (* 2 (alength bytes))))]
    (if (== (alength bytes) index)
      (.toString buffer)
      (let [byte (aget bytes index)]
        (.append
          buffer
          (aget hex-digits (bit-and (bit-shift-right byte 4) 15)))
        (.append buffer (aget hex-digits (bit-and byte 15)))
        (recur (inc index) buffer)))))
(defn map-merge [a b]
  (if (and (map? a) (map? b))
    (loop [ks (seq (keys a)) ret a b' b]
      (if ks
        (let [k (first ks)]
          (if (contains? b' k)
            (recur
              (next ks)
              (assoc ret k (map-merge (get ret k) (get b' k)))
              (dissoc b' k))
            (recur (next ks) ret b')))
        (merge ret b')))
    a))
(defn relative-name
  "Given a file return a path relative to the working directory. Given a\n   URL return the JAR relative path of the resource."
  [x]
  {:pre [(or (file? x) (url? x))]}
  (letfn
    [(strip-user-dir
       [s]
       (let [user-path (.toPath
                         (io/file (System/getProperty "user.dir")))
             base-count (.getNameCount user-path)
             file-path (.toPath (io/file s))]
         (if (.startsWith file-path user-path)
           (str
             (.subpath file-path base-count (.getNameCount file-path)))
           s)))]
    (if (file? x)
      (strip-user-dir (.getAbsolutePath x))
      (let [f (URLDecoder/decode (.getFile x))]
        (if (string/includes? f ".jar!/")
          (last (string/split f #"\.jar!/"))
          (strip-user-dir f))))))
(defn to-target-file
  ([target-dir ns-info] (to-target-file target-dir ns-info "js"))
  ([target-dir {:keys [ns source-file]  :as ns-info} ext]
    (let [src-ext (if source-file (cljs.util/ext source-file) "cljs")
          ns (if (or
                   (= src-ext "clj")
                   (and (= ns (quote cljs.core)) (= src-ext "cljc")))
               (symbol (str ns "$macros"))
               ns)
          relpath (string/split (munge-path (str ns)) #"\.")
          parents (cond->
                    (butlast relpath)
                    target-dir
                    (conj target-dir))]
      (cond->>
        (io/file (str (last relpath) (str "." ext)))
        (seq parents)
        (io/file (to-path parents))))))
(clojure.core/defn measure
  "Like cljs.core/time but toggleable and takes a message string."
  {:added "1.0"}
  ([&form &env msg expr]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.util/measure))
        (clojure.core/list (quote true))
        (clojure.core/list msg)
        (clojure.core/list expr))))
  ([&form &env enable msg expr]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote if))
        (clojure.core/list enable)
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/let))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote start__776__auto__))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote .))
                            (clojure.core/list
                              (quote java.lang.System))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.util/nanoTime))))))))
                      (clojure.core/list (quote ret__777__auto__))
                      (clojure.core/list expr)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.util/debug-prn))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote clojure.core/str))
                          (clojure.core/list msg)
                          (clojure.core/list ", elapsed time:"))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote clojure.core//))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/double))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote clojure.core/-))
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote .))
                                            (clojure.core/list
                                              (quote java.lang.System))
                                            (clojure.core/list
                                              (clojure.core/seq
                                                (clojure.core/concat
                                                  (clojure.core/list
                                                    (quote
                                                      cljs.util/nanoTime))))))))
                                      (clojure.core/list
                                        (quote
                                          start__776__auto__))))))))
                          (clojure.core/list 1000000.0))))
                    (clojure.core/list "msecs"))))
              (clojure.core/list (quote ret__777__auto__)))))
        (clojure.core/list expr)))))
(defn get-name
  "Given a file or url return the last component of the path."
  [x]
  {:pre [(or (file? x) (url? x))]}
  (if (file? x) (filename x) (last (string/split (path x) #"[\\\/]"))))
(defn normalize-path [x]
  (-> (cond-> x windows? (string/replace #"^[\\/]" ""))
   (string/replace "\\" File/separator)
   (string/replace "/" File/separator)))
(defn ext
  "Given a file, url or string return the file extension."
  [x]
  (let [s (cond
            (file? x) (filename x)
            (url? x) (path x)
            (string? x) x
            :else (throw
                    (Exception.
                      (str
                        "Expected file, url, or string. Got "
                        (pr-str x)))))]
    (last (string/split s #"\."))))
(defn last-modified [src]
  (cond
    (file? src) (.lastModified src)
    (url? src) (let [conn (.openConnection src)]
                 (try
                   (.getLastModified conn)
                   (finally
                     (let [ins (.getInputStream conn)]
                       (when ins (.close ins))))))
    :else (throw
            (IllegalArgumentException.
              (str "Cannot get last modified for " src)))))
(defn path [x]
  (cond
    (file? x) (.getAbsolutePath x)
    (url? x) (if windows?
               (let [f (URLDecoder/decode (.getFile x))]
                 (normalize-path f))
               (.getPath x))
    (string? x) x
    :else (throw
            (Exception.
              (str "Expected file, url, or string. Got " (pr-str x))))))
(defn clojurescript-version
  "Returns clojurescript version as a printable string."
  []
  (if (bound? (var *clojurescript-version*))
    (str
      (:major *clojurescript-version*)
      "."
      (:minor *clojurescript-version*)
      (when-let [i (:incremental *clojurescript-version*)] (str "." i))
      (when-let [q (:qualifier *clojurescript-version*)] (str "." q))
      (when (:interim *clojurescript-version*) "-SNAPSHOT"))
    (clojure.core/deref synthetic-clojurescript-version)))
(clojure.core/defn compile-if
  ([&form &env exp then]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.util/compile-if))
        (clojure.core/list exp)
        (clojure.core/list then)
        (clojure.core/list (quote nil)))))
  ([&form &env exp then else]
    (if (try (eval exp) (catch Throwable _ false))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list then)))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list else))))))
(clojure.core/defn compile-when
  ([&form &env exp then]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.util/compile-if))
        (clojure.core/list exp)
        (clojure.core/list then)
        (clojure.core/list (quote nil))))))
(defn synthetic-version?
  "Returns true if clojurescript-version returns a synthetically-generated\n   version."
  []
  (string/starts-with?
    (clojurescript-version)
    synthethetic-version-prefix))
(defn conjunction-str [xs]
  (let [xs (vec xs)]
    (case
      (count xs)
      1
      (first xs)
      2
      (str (first xs) " and " (second xs))
      (str (string/join ", " (pop xs)) " and " (peek xs)))))
(defn file-or-resource [s]
  (or (and (.exists (io/file s)) (io/file s)) (io/resource s)))
(defn topo-sort
  ([x get-deps] (topo-sort x 0 (atom (sorted-map)) (memoize get-deps)))
  ([x depth state memo-get-deps]
    (let [deps (memo-get-deps x)]
      (swap! state update-in [depth] (fnil into #{}) deps)
      (doseq [dep deps]
        (topo-sort dep (inc depth) state memo-get-deps))
      (doseq [[ _] (subseq (clojure.core/deref state) < depth)]
        (swap! state update-in [] set/difference deps))
      (when (= depth 0)
        (distinct (apply concat (vals (clojure.core/deref state))))))))
(defn cljs-built-dep?
  "Returns true if ClojureScript itself is a built dep."
  []
  (not (synthetic-version?)))
cljs.source-map.base64 14/16 (87.5%)
(defn encode [n]
  (case
    n
    0
    \A
    1
    \B
    2
    \C
    3
    \D
    4
    \E
    5
    \F
    6
    \G
    7
    \H
    8
    \I
    9
    \J
    10
    \K
    11
    \L
    12
    \M
    13
    \N
    14
    \O
    15
    \P
    16
    \Q
    17
    \R
    18
    \S
    19
    \T
    20
    \U
    21
    \V
    22
    \W
    23
    \X
    24
    \Y
    25
    \Z
    26
    \a
    27
    \b
    28
    \c
    29
    \d
    30
    \e
    31
    \f
    32
    \g
    33
    \h
    34
    \i
    35
    \j
    36
    \k
    37
    \l
    38
    \m
    39
    \n
    40
    \o
    41
    \p
    42
    \q
    43
    \r
    44
    \s
    45
    \t
    46
    \u
    47
    \v
    48
    \w
    49
    \x
    50
    \y
    51
    \z
    52
    \0
    53
    \1
    54
    \2
    55
    \3
    56
    \4
    57
    \5
    58
    \6
    59
    \7
    60
    \8
    61
    \9
    62
    \+
    63
    \/
    (throw (Error. (str "Must be between 0 and 63: " n)))))
(defn decode [c]
  (let [e (find char->int c)]
    (if e
      (second e)
      (throw (Error. (str "Not a valid base 64 digit: " c))))))
cljs.build.api 64/313 (20.4%)
(defn build
  "Given compiler options, produce runnable JavaScript. An optional source\n   parameter may be provided."
  ([opts] (build nil opts))
  ([source opts]
    (build
      source
      opts
      (or
        (ana-api/current-state)
        (ana-api/empty-state
          (closure/add-externs-sources (dissoc opts :foreign-libs))))))
  ([source opts compiler-env]
    (doseq [[unknown-opt suggested-opt] (util/unknown-opts
                                          (set (keys opts))
                                          closure/known-opts)]
      (when suggested-opt
        (println
          (str
            "WARNING: Unknown compiler option '"
            unknown-opt
            "'. Did you mean '"
            suggested-opt
            "'?"))))
    (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                            opts
                                            ana/*cljs-warning-handlers*)]
      (closure/build source opts compiler-env))))
(defn target-file-for-cljs-ns
  "Given an output directory and a clojurescript namespace return the\n  compilation target file for that namespace.\n\n  For example:\n  (target-file-from-cljs-ns \"resources/out\" 'example.core) ->\n  "
  ([ns-sym] (closure/target-file-for-cljs-ns ns-sym nil))
  ([ns-sym output-dir]
    (closure/target-file-for-cljs-ns ns-sym output-dir)))
(defn cljs-dependents-for-macro-namespaces
  "Takes a list of Clojure (.clj) namespaces that define macros and\n  returns a list ClojureScript (.cljs) namespaces that depend on those macro\n  namespaces.\n\n  For example where example.macros is defined in the clojure file\n  \"example/macros.clj\" and both 'example.core and 'example.util are\n  ClojureScript namespaces that require and use the macros from\n  'example.macros :\n  (cljs-dependents-for-macro-namespaces 'example.macros) ->\n  ('example.core 'example.util)"
  ([namespaces]
    (closure/cljs-dependents-for-macro-namespaces
      (or (ana-api/current-state) (ana-api/empty-state))
      namespaces))
  ([state namespaces]
    (closure/cljs-dependents-for-macro-namespaces state namespaces)))
(defn get-node-deps
  "EXPERIMENTAL: Get the Node.js dependency graph of the supplied dependencies.\n   Dependencies must be a sequence of strings or symbols naming packages or paths\n   within packages (e.g. [react \"react-dom/server\"] or a valid compiler options\n   map. Assumes dependencies have been been previously installed, either by\n   `cljs.build.api/install-node-deps!` or by an NPM client, and reside in the\n   `node_modules` directory."
  ([dependencies]
    (if (compiler-opts? dependencies)
      (get-node-deps (keys (:npm-deps dependencies)) dependencies)
      (get-node-deps
        dependencies
        (when-let [state (ana-api/current-state)]
          (:options (clojure.core/deref state))))))
  ([dependencies opts]
    {:pre [(sequential? dependencies)]}
    (closure/index-node-modules
      (distinct
        (concat (keys (:npm-deps opts)) (map str dependencies)))
      opts)))
(defn install-node-deps!
  "EXPERIMENTAL: Install the supplied dependencies via NPM. dependencies must be\n   a map of name to version or a valid compiler options map."
  ([dependencies]
    (if (compiler-opts? dependencies)
      (install-node-deps! (:npm-deps dependencies) dependencies)
      (install-node-deps!
        dependencies
        (when-let [state (ana-api/current-state)]
          (:options (clojure.core/deref state))))))
  ([dependencies opts]
    {:pre [(map? dependencies)]}
    (closure/check-npm-deps opts)
    (closure/maybe-install-node-deps!
      (update-in opts [:npm-deps] merge dependencies))))
(defn inputs
  "Given a list of directories and files, return a compilable object that may\n  be passed to build or watch."
  [& xs]
  (reify
    closure/Inputs
    (-paths [_] (map io/file xs))
    closure/Compilable
    (-compile
      [_ opts]
      (letfn
        [(compile-input
           [x]
           (let [compiled (closure/-compile x opts)]
             (if (sequential? compiled) compiled [compiled])))]
        (mapcat compile-input xs)))
    (-find-sources
      [_ opts]
      (mapcat
        (fn* [p1__14313#] (closure/-find-sources p1__14313# opts))
        xs))))
(defn goog-dep-string
  "Given compiler options and a IJavaScript instance return the corresponding\n  goog.addDependency string"
  [opts ijs]
  (closure/add-dep-string opts ijs))
(defn compilable->ijs
  "Given a cljs.closure/Compilable value, return the corresponding\n  cljs.closure/IJavaScript value."
  ([x] (compilable->ijs x {}))
  ([x opts] (closure/-find-sources x opts)))
(defn src-file->target-file
  "Given a ClojureScript source file return the target file. May optionally\n  provide build options with :output-dir specified."
  ([src] (src-file->target-file src nil))
  ([src opts]
    (src-file->target-file
      (or (ana-api/current-state) (ana-api/empty-state opts))
      src
      opts))
  ([state src opts]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (closure/src-file->target-file src opts)))))
(defn output-unoptimized
  "Ensure that all JavaScript source files are on disk (not in jars),\n   write the goog deps file including only the libraries that are being\n   used and write the deps file for the current project.\n\n   The deps file for the current project will include third-party\n   libraries."
  [opts & sources]
  (apply closure/output-unoptimized opts sources))
(defn add-dependencies
  "DEPRECATED: Given one or more IJavaScript objects in dependency order, produce\n  a new sequence of IJavaScript objects which includes the input list\n  plus all dependencies in dependency order."
  [opts & ijss]
  (closure/add-dependencies opts ijss))
(defn mark-cljs-ns-for-recompile!
  "Backdates a cljs target file so that it the cljs compiler will recompile it."
  ([ns-sym] (closure/mark-cljs-ns-for-recompile! ns-sym nil))
  ([ns-sym output-dir]
    (closure/mark-cljs-ns-for-recompile! ns-sym output-dir)))
(defn parse-js-ns
  "Given a Google Closure style JavaScript file or resource return the namespace\n  information for the given file. Only returns the value extracted from the\n  first provide statement."
  [f]
  (closure/parse-js-ns f))
(defn src-file->goog-require
  "Given a ClojureScript or Google Closure style JavaScript source file return\n  the goog.require statement for it."
  ([src] (src-file->goog-require src nil))
  ([src opts]
    (src-file->goog-require
      (or (ana-api/current-state) (ana-api/empty-state opts))
      src
      opts))
  ([state src opts]
    (ana-api/with-state
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (closure/src-file->goog-require src opts)))))
(defn source-on-disk
  "Ensure that the given IJavaScript exists on disk in the output directory.\n  Return updated IJavaScript with the new location if necessary."
  [opts ijs]
  (closure/source-on-disk opts ijs))
(defn compile
  "Given a Compilable, compile it and return an IJavaScript."
  ([opts compilable]
    (compile
      (or (ana-api/current-state) (ana-api/empty-state opts))
      opts
      compilable))
  ([state opts compilable]
    (ana-api/with-state state (closure/compile compilable opts))))
(defn ns->source
  "Given a namespace as a symbol return the corresponding resource if it exists."
  [ns]
  (util/ns->source ns))
(defn watch
  "Given a source which can be compiled, watch it for changes to produce."
  ([source opts]
    (watch
      source
      opts
      (or
        (ana-api/current-state)
        (ana-api/empty-state (closure/add-externs-sources opts)))))
  ([source opts compiler-env] (watch source opts compiler-env nil))
  ([source opts compiler-env stop]
    (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                            opts
                                            ana/*cljs-warning-handlers*)]
      (closure/watch source opts compiler-env stop))))
(defn compiler-opts? [m]
  (and
    (map? m)
    (or
      (contains? m :output-to)
      (contains? m :modules)
      (contains? m :npm-deps)
      (contains? m :main)
      (contains? m :optimizations)
      (contains? m :foreign-libs))))
(defn node-modules
  "Return a sequence of requirable libraries found under node_modules."
  ([] (node-modules {}))
  ([opts]
    (ana-api/with-state
      (or (ana-api/current-state) (ana-api/empty-state opts))
      (filter :provides (closure/index-node-modules-dir)))))
(defn index-ijs
  "Given a sequence of cljs.closure/IJavaScript values, create an index using\n  :provides. The original values will appear under each :provide."
  [xs]
  (reduce
    (fn [index x] (merge index (zipmap (:provides x) (repeat x))))
    {}
    xs))
(defn node-inputs
  "EXPERIMENTAL: return the foreign libs entries as computed by running\n   the module-deps package on the supplied JavaScript entry points. Assumes\n   that the `@cljs-oss/module-deps` NPM package is either locally or globally\n   installed."
  ([entries]
    (node-inputs
      entries
      (:options (or (ana-api/current-state) (ana-api/empty-state)))))
  ([entries opts] (closure/node-inputs entries opts)))
(defn dependency-order
  "Topologically sort a collection of IJavaScript values."
  [xs]
  (deps/dependency-order xs))
(defn add-implicit-options
  "Given a valid map of build options add any standard implicit options. For\n  example :optimizations :none implies :cache-analysis true and :source-map\n  true."
  [opts]
  (closure/add-implicit-options opts))
(defn add-dependency-sources
  "Given a sequence of cljs.closure/IJavaScript values, return a set that includes\n  all dependencies."
  ([xs] (add-dependency-sources xs {}))
  ([xs opts]
    (add-dependency-sources
      (or (ana-api/current-state) (ana-api/empty-state opts))
      xs
      opts))
  ([state xs opts]
    (ana-api/with-state
      state
      (closure/add-dependency-sources xs opts))))
(defn ns->location
  "Given a namespace and compilation environment return the relative path and\n  uri of the corresponding source regardless of the source language extension:\n  .cljs, .cljc, .js. Returns a map containing :relative-path a string, and\n  :uri a URL."
  ([ns]
    (ns->location
      ns
      (or (ana-api/current-state) (ana-api/empty-state))))
  ([ns compiler-env] (closure/source-for-namespace ns compiler-env)))
(defn handle-js-modules
  "Given a collection of IJavaScript values representing a build, index all\n  node modules, convert all JS modules (ES6 etc), and store the updated\n  js-dependency-index (likely changed due to modules) in compiler state."
  [state xs opts]
  (closure/handle-js-modules opts xs state))
cljs.support 40/40 (100.0%)
(clojure.core/defn assert-args
  "Internal - do not use!"
  ([&form &env fnname & pairs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote do))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/when-not))
              (clojure.core/list (first pairs))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote throw))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/ex-info))
                          (clojure.core/list
                            (str fnname " requires " (second pairs)))
                          (clojure.core/list
                            (clojure.core/apply
                              clojure.core/hash-map
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    :clojure.error/phase)
                                  (clojure.core/list
                                    :macro-syntax-check))))))))))))))
        (clojure.core/list
          (let [more (nnext pairs)]
            (when more
              (list*
                (quote cljs.support/assert-args)
                fnname
                more))))))))
cljs.build-api-tests 24/24 (100.0%)
(defn loader-test-project [output-dir]
  {:inputs (str (io/file "src" "test" "cljs_build" "loader_test")) 
   :opts
   {:output-dir output-dir 
    :optimizations :none 
    :language-in :es6 
    :verbose true 
    :foreign-libs
    [{:file "src/test/cljs_build/loader_test/foreignA.js" 
      :provides ["foreign.a"]}
     {:file "src/test/cljs_build/loader_test/foreignB.js" 
      :provides ["foreign.b"] 
      :requires ["foreign.a"]}] 
    :modules
    {:foo
     {:output-to (str (io/file output-dir "foo.js")) 
      :entries #{(quote loader-test.foo)}} 
     :bar
     {:output-to (str (io/file output-dir "bar.js")) 
      :entries #{(quote loader-test.bar)}}}}})
(defn collecting-warning-handler [state]
  (fn [warning-type env extra]
    (when (warning-type ana/*cljs-warnings*)
      (when-let [s (ana/error-message warning-type extra)]
        (swap! state conj s)))))
cljs.reader 49/49 (100.0%)
(clojure.core/defn add-data-readers
  ([&form &env default-readers]
    (let [data-readers (->>
                         (get
                           (clojure.core/deref env/*compiler*)
                           :cljs.analyzer/data-readers)
                         (map
                           (fn [[k v]]
                             (clojure.core/apply
                               clojure.core/vector
                               (clojure.core/seq
                                 (clojure.core/concat
                                   (clojure.core/list
                                     (clojure.core/seq
                                       (clojure.core/concat
                                         (clojure.core/list
                                           (quote quote))
                                         (clojure.core/list k))))
                                   (clojure.core/list
                                     (clojure.core/seq
                                       (clojure.core/concat
                                         (clojure.core/list
                                           (quote clojure.core/fn))
                                         (clojure.core/list
                                           (clojure.core/apply
                                             clojure.core/vector
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote
                                                     x__129169__auto__))))))
                                         (clojure.core/list
                                           (clojure.core/seq
                                             (clojure.core/concat
                                               (clojure.core/list
                                                 (vary-meta
                                                   (-> v meta :sym)
                                                   assoc
                                                   :cljs.analyzer/no-resolve
                                                   true))
                                               (clojure.core/list
                                                 (quote
                                                   x__129169__auto__)))))))))))))
                         (into {}))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote clojure.core/merge))
                (clojure.core/list default-readers)
                (clojure.core/list data-readers)))))))))
cljs.analyzer-api-tests 8/8 (100.0%)
(defn warning-handler [counter]
  (fn [warning-type env extra]
    (when (ana-api/warning-enabled? warning-type) (swap! counter inc))))
cljs.module-graph 598/660 (90.6%)
(defn sort-modules [modules-with-base]
  (into
    []
    (map (fn [module] [module (module modules-with-base)]))
    (topo-sort modules-with-base :depends-on)))
(defn deepest-common-parent
  "Given a set of modules and a compiler :modules graph, compute the deepest\n  common parent module."
  [modules all-modules]
  (let [common-parents (reduce
                         set/intersection
                         (map
                           (fn*
                             [p1__11997#]
                             (conj
                               (set
                                 (deps-for-module
                                   p1__11997#
                                   all-modules))
                               p1__11997#))
                           modules))]
    (apply
      max-key
      (fn [p] (get-in all-modules [p :depth]))
      common-parents)))
(defn index-inputs
  "Index compiler inputs by :provides. If an input has multiple entries\n  in :provides will result in multiple entries in the map. The keys will be munged\n  strings not symbols."
  [inputs]
  (reduce
    (fn [ret {:keys [provides]  :as input}]
      (into
        ret
        (map
          (fn [provide]
            (vector
              (-> provide comp/munge str)
              (-> input normalize-input))))
        provides))
    {}
    inputs))
(defn add-cljs-base-dep
  "Adds :cljs-base to any module in compiler :modules with an empty :depends-on."
  [modules]
  (reduce-kv
    (fn [ret k {:keys [depends-on]  :as module-info}]
      (assoc
        ret
        k
        (cond->
          module-info
          (and (not= :cljs-base k) (empty? depends-on))
          (assoc :depends-on [:cljs-base]))))
    {}
    modules))
(defn annotate-depths
  "Annotate all modules in compiler :modules with depth information."
  [modules]
  (reduce-kv
    (fn [ret module-name module]
      (let [module' (assoc
                      module
                      :depth
                      (depth-of module-name modules))]
        (assoc ret module-name module')))
    {}
    modules))
(defn modules->module-infos
  "Given a :modules map return a Closure module info map which maps modules\n   to depended upon modules."
  [modules]
  (let [modules (-> modules add-cljs-base add-cljs-base-dep)]
    (reduce-kv
      (fn [ret
           module-name
           {:keys [depends-on]  :or {depends-on []}  :as module}]
        (assoc ret module-name depends-on))
      {}
      modules)))
(defn deps-for-module
  "Return all dependencies of a module using compiler :modules."
  [module modules]
  (deps-for module modules :depends-on))
(defn module-for
  "Given an entry find the module it belongs to."
  [entry modules]
  (let [modules' (normalize modules) entry' (str (comp/munge entry))]
    (->>
      modules'
      (some
        (fn [[module-name {:keys [entries]} :as me]]
          (when (some #{entry'} entries) me)))
      first)))
(defn normalize
  "Normalize compiler :modules. All symbols in a module :entries will be\n  converted into munged strings."
  [modules]
  (reduce-kv
    (fn [ret module-name module]
      (assoc
        ret
        module-name
        (update
          module
          :entries
          (fn [es] (into #{} (map (comp str comp/munge)) es)))))
    {}
    modules))
(defn topo-sort
  "Topologically sort a graph using the given edges-key."
  [graph edges-key]
  (letfn
    [(no-incoming-edges
       [graph edges-key]
       (->>
         graph
         (filter
           (fn [[k v]]
             (every?
               (fn* [p1__12090#] (not (contains? graph p1__12090#)))
               (edges-key v))))
         (map first)))]
    (when-not (empty? graph)
      (let [nodes (no-incoming-edges graph edges-key)
            graph' (reduce
                     (fn*
                       [p1__12091# p2__12092#]
                       (dissoc p1__12091# p2__12092#))
                     graph
                     nodes)]
        (concat nodes (topo-sort graph' edges-key))))))
(defn expand-modules
  "Given compiler :modules and a dependency sorted list of compiler inputs return\n   a complete :modules map where all depended upon inputs are assigned."
  [modules inputs]
  (let [order (first
                (reduce
                  (fn [[ret n] {:keys [provides]}] [(merge
                                                      ret
                                                      (zipmap
                                                        (map
                                                          (comp
                                                            str
                                                            comp/munge)
                                                          provides)
                                                        (repeat n)))
                                                    (inc n)])
                  [{} 0]
                  inputs))
        modules' (-> modules normalize add-cljs-base add-cljs-base-dep)
        assigns (inputs->assigned-modules
                  inputs
                  (annotate-depths modules'))
        um (reduce-kv
             (fn [ret entry module-name]
               (update-in
                 ret
                 [module-name :entries]
                 (fnil conj #{})
                 entry))
             modules'
             assigns)]
    (reduce-kv
      (fn [ret module-name {:keys [entries]}]
        (update-in
          ret
          [module-name :entries]
          (fn* [p1__12072#] (vec (sort-by order p1__12072#)))))
      um
      um)))
(defn normalize-input [input]
  (-> input
   (update
     :provides
     (fn*
       [p1__11957#]
       (into [] (map (comp str comp/munge)) p1__11957#)))
   (update
     :requires
     (fn*
       [p1__11958#]
       (into [] (map (comp str comp/munge)) p1__11958#)))))
(defn deps-for-entry
  "Return all dependencies for an entry using a compiler inputs index."
  [entry indexed-inputs]
  (map
    (fn* [p1__11992#] (-> p1__11992# comp/munge str))
    (deps-for entry indexed-inputs :requires)))
(defn depth-of
  "Compute the depth of module-name based on dependency information in\n   compiler :modules."
  [module-name modules]
  (if (= module-name :cljs-base)
    0
    (let [mns (get-in modules [module-name :depends-on])]
      (if (empty? mns)
        1
        (apply max (map (fn [mn] (+ 1 (depth-of mn modules))) mns))))))
(defn add-cljs-base
  "Adds :cljs-base module to compiler :modules if not already present."
  [modules]
  (cond->
    modules
    (not (contains? modules :cljs-base))
    (assoc :cljs-base {})))
(defn inputs->assigned-modules
  "Given compiler inputs assign each to a single module. This is done by first\n  starting with :entries. Dependencies for every entry in a module are also added\n  to that module. Inputs may of course be assigned to several modules initially\n  but we must eventually choose one. User supplied module :entries are respected\n  but all other input assignments are computed automatically via\n  deepest-common-parent. This function returns a map assigning all inputs (indexed\n  by munged name) to a single module. Any orphan inputs will be assigned to\n  :cljs-base."
  [inputs modules]
  (let [index (index-inputs inputs)
        _ (validate-modules modules index)
        deps (fn* [p1__12041#] (deps-for-entry p1__12041# index))
        assign1 (fn [[entry maybe-assigned]] [entry
                                              (if
                                                (=
                                                  1
                                                  (count
                                                    maybe-assigned))
                                                (first maybe-assigned)
                                                (deepest-common-parent
                                                  maybe-assigned
                                                  modules))])
        canon (fn [xs]
                (into
                  #{}
                  (map
                    (fn*
                      [p1__12042#]
                      (canonical-name p1__12042# index)))
                  xs))
        assigns (fn [f ms]
                  (binding [deps-for (memoize deps-for)]
                    (reduce-kv
                      (fn [ret
                           module-name
                           {:keys [entries]  :as module}]
                        (let [entries' (canon entries)]
                          (reduce
                            (fn [ret entry]
                              (update
                                ret
                                entry
                                (fnil conj #{})
                                module-name))
                            ret
                            (canon (f entries')))))
                      {}
                      ms)))
        e->ms (assigns identity modules)
        d->ms (assigns
                (fn* [p1__12043#] (distinct (mapcat deps p1__12043#)))
                modules)
        e&d->ms (merge-with into e->ms d->ms)
        orphans {:cljs-base
                 {:entries
                  (->>
                    (reduce-kv
                      (fn [m k _]
                        (reduce dissoc m (get-in m [k :provides])))
                      index
                      e&d->ms)
                    vals
                    (map (comp str comp/munge first :provides))
                    set)}}
        o->ms (assigns identity orphans)
        od->ms (assigns
                 (fn* [p1__12044#] (distinct (mapcat deps p1__12044#)))
                 orphans)
        all->ms (merge-with into e&d->ms o->ms od->ms)]
    (into {} (map assign1) all->ms)))
(defn validate-inputs* [indexed path seen validated]
  (let [ns (peek path) {:keys [requires]} (get indexed ns)]
    (doseq [ns' requires]
      (if (contains? seen ns')
        (throw
          (ex-info
            (str
              "Circular dependency detected "
              (apply str (interpose " -> " (conj path ns'))))
            {:cljs.closure/error :invalid-inputs 
             :clojure.error/phase :compilation}))
        (when-not (contains? (clojure.core/deref validated) ns)
          (validate-inputs*
            indexed
            (conj path ns')
            (conj seen ns')
            validated))))
    (swap! validated conj ns)))
(defn validate-inputs
  "Throws on the presence of circular dependencies"
  ([inputs] (validate-inputs inputs [] #{}))
  ([inputs path seen]
    (let [indexed (index-inputs inputs) validated (atom #{})]
      (binding []
        (doseq [{:keys [provides]} (map normalize-input inputs)]
          (let [ns (first provides)]
            (validate-inputs*
              indexed
              (conj path ns)
              (conj seen ns)
              validated)
            (swap! validated conj ns)))))))
(defn modules->module-uris
  "Given a :modules map, a dependency sorted list of compiler inputs, and\n   compiler options return a Closure module uris map. This map will include\n   all inputs by leveraging expand-modules."
  [modules
   inputs
   {:keys [optimizations asset-path output-dir]  :as opts}]
  (assert optimizations "Must supply :optimizations in opts map")
  (assert
    (#{:whitespace :simple :advanced :none} optimizations)
    "Must supply valid :optimizations in opts map")
  (assert output-dir "Must supply :output-dir in opts map")
  (letfn
    [(get-uri
       [rel-path]
       (cond->> rel-path asset-path (str asset-path)))
     (get-rel-path*
       [output-dir file]
       (-> (.. (io/file file) getAbsoluteFile getPath)
        (string/replace output-dir "")
        (string/replace #"[\\/]" "/")))]
    (let [get-rel-path (partial
                         get-rel-path*
                         (.. (io/file output-dir)
                          getAbsoluteFile
                          getPath))]
      (case
        optimizations
        :none
        (into
          {}
          (map
            (fn [[module-name {:keys [entries]  :as module}]] [module-name
                                                               (into
                                                                 []
                                                                 (comp
                                                                   (mapcat
                                                                     (fn*
                                                                       [p1__12115#]
                                                                       (find-sources-for-module-entry
                                                                         p1__12115#
                                                                         inputs)))
                                                                   (map
                                                                     (comp
                                                                       get-uri
                                                                       get-rel-path
                                                                       (fn 
                                                                         [{:keys
                                                                           [out-file] 
                                                                           :as
                                                                           ijs}]
                                                                         (if-not
                                                                           out-file
                                                                           (throw
                                                                             (util/compilation-error
                                                                               (Exception.
                                                                                 (str
                                                                                   "No :out-file for IJavaScript "
                                                                                   (pr-str
                                                                                     ijs)))))
                                                                           out-file))
                                                                       (fn*
                                                                         [p1__12116#]
                                                                         (maybe-add-out-file
                                                                           p1__12116#
                                                                           opts))))
                                                                   (distinct))
                                                                 entries)]))
          (expand-modules modules inputs))
        (:advanced :simple :whitespace)
        (reduce-kv
          (fn [ret k {:keys [output-to]}]
            (assert
              output-to
              (str "Module " k " does not specify :output-to"))
            (assoc ret k [(-> output-to get-rel-path get-uri)]))
          {:cljs-base
           [(-> (or
                  (get-in modules [:cljs-base :output-to])
                  (io/file output-dir "cljs_base.js"))
             get-rel-path
             get-uri)]}
          modules)))))
(defn validate-modules
  "Check that a compiler :modules map does not contain user supplied duplicates.\n   Throws if modules fails validation."
  [modules indexed-inputs]
  (let [seen (atom {})]
    (doseq [[module-name {:keys [entries]  :as module}] modules]
      (let [entries (into
                      #{}
                      (map
                        (fn*
                          [p1__12005#]
                          (canonical-name p1__12005# indexed-inputs)))
                      entries)]
        (doseq [entry entries]
          (let [seen' (clojure.core/deref seen)]
            (if-some
              [module-name' (get seen' entry)]
              (throw
                (util/compilation-error
                  (Exception.
                    (str
                      "duplicate entry \""
                      entry
                      "\", occurs in "
                      module-name
                      " and "
                      module-name'
                      ". entry :provides is "
                      (get-in indexed-inputs [entry :provides])))))
              (swap! seen assoc entry module-name))))))))
(defn canonical-name
  "Given an entry use indexed-inputs to return the canonical name. Throws if\n   entry cannot be found."
  [entry indexed-inputs]
  (if-let [entry (get indexed-inputs (-> entry comp/munge str))]
    (-> (:provides entry) first comp/munge str)
    (throw
      (util/compilation-error
        (Exception. (str "No input matching \"" entry "\""))))))
(defn deps-for
  "Return all dependencies for x in a graph using deps-key."
  [x graph deps-key]
  (let [requires (get-in graph [x deps-key])]
    (try
      (-> (mapcat
            (fn* [p1__11988#] (deps-for p1__11988# graph deps-key))
            requires)
       (concat requires)
       distinct
       vec)
      (catch
        Throwable
        t
        (throw
          (ex-info
            (str "Failed to compute deps for " x)
            {:lib x  :requires requires}
            t))))))
(defn find-sources-for-module-entry
  "Given an entry as a symbol, find all matching inputs in sources. If the\n  symbol ends in a *, then the symbol will be treated as a wildcard. This\n  function returns a set and is not order preserving. If there are no matches\n  returns nil."
  [entry sources]
  (let [m (name (comp/munge entry)) xs (string/split m #"\.")]
    (if (= "_STAR_" (last xs))
      (let [matcher (str (string/join "." (butlast xs)) ".")
            matches (into
                      #{}
                      (filter
                        (fn [source]
                          (when (some
                                  (fn*
                                    [p1__11928#]
                                    (.startsWith p1__11928# matcher))
                                  (map
                                    (comp str comp/munge)
                                    (:provides source)))
                            source)))
                      sources)]
        (when-not (empty? matches) matches))
      (when-let [input (some
                         (fn [source]
                           (let [matcher
                                 (into
                                   #{}
                                   [(name entry)
                                    (name (comp/munge entry))])]
                             (when (some
                                     matcher
                                     (map
                                       (comp str comp/munge)
                                       (:provides source)))
                               source)))
                         sources)]
        #{input}))))
(defn maybe-add-out-file [{:keys [lib-path]  :as ijs}
                          {:keys [output-dir]  :as opts}]
  (if-not lib-path
    ijs
    (if (parent? lib-path output-dir)
      (assoc ijs :out-file lib-path)
      ijs)))
(defn parent? [f0 f1]
  (.startsWith
    (.getAbsolutePath (io/file f0))
    (.getAbsolutePath (io/file f1))))
cljs.module-graph-tests 29/29 (100.0%)
(defn modules [{:keys [output-dir]  :as opts}]
  {:shared
   {:entries (quote [shared.a shared.b]) 
    :output-to (str output-dir "/shared.js")} 
   :page1
   {:entries (quote [page1.a page1.b]) 
    :depends-on [:shared] 
    :output-to (str output-dir "/page1.js")} 
   :page2
   {:entries (quote [page2.a page2.b]) 
    :depends-on [:shared] 
    :output-to (str output-dir "/page2.js")}})
(defn inputs
  ([] (inputs {:output-dir "out"}))
  ([{:keys [output-dir]  :as opts}]
    [{:provides (quote [goog]) 
      :out-file (str output-dir "/goog/base.js")}
     {:provides (quote [cljs.core]) 
      :out-file (str output-dir "/cljs/core.js")}
     {:provides ["cljs.reader"] 
      :requires ["cljs.core"] 
      :out-file (str output-dir "/cljs/reader.js")}
     {:provides (quote [events "event.types"]) 
      :requires ["cljs.core"] 
      :out-file (str output-dir "/events.js")}
     {:provides (quote [shared.a]) 
      :requires ["cljs.core"] 
      :out-file (str output-dir "/shared/a.js")}
     {:provides (quote [shared.b]) 
      :requires (quote [cljs.core]) 
      :out-file (str output-dir "/shared/b.js")}
     {:provides ["page1.a"] 
      :requires ["cljs.core" "cljs.reader" "events" (quote shared.a)] 
      :out-file (str output-dir "/page1/a.js")}
     {:provides ["page1.b"] 
      :requires (quote [cljs.core shared.b]) 
      :out-file (str output-dir "/page1/b.js")}
     {:provides ["page2.a"] 
      :requires ["cljs.core" "events" (quote shared.a)] 
      :out-file (str output-dir "/page2/a.js")}
     {:provides ["page2.b"] 
      :requires [(quote cljs.core) (quote shared.b)] 
      :out-file (str output-dir "/page2/b.js")}]))
cljs.repl 23/2254 (1.0%)
(extend-type Object IReplEnvOptions (-repl-options [_] nil))
(defn- wrap-special-fns [wfn fns]
  "Wrap wfn around all (fn) values in fns hashmap."
  (into {} (for [[k v] fns] [k (wfn v)])))
(clojure.core/defn err-out
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote clojure.core/*out*))
                (clojure.core/list (quote clojure.core/*err*))))))
        body))))
(defn- wrap-self
  "Takes a self-ish fn and returns it wrapped with exception handling.\n  Compiler state is restored if self-ish fn fails."
  [f]
  (fn g
    ([a b c] (g a b c nil))
    ([a b c d]
      (let [backup-comp (clojure.core/deref env/*compiler*)]
        (try
          (apply f [a b c d])
          (catch
            Exception
            e
            (reset! env/*compiler* backup-comp)
            (throw e)))))))
(defn ns-info
  "Given a path to a js source file return the ns info for the corresponding\n   ClojureScript file if it exists."
  [f]
  (let [f' (js-src->cljs-src f)]
    (when (and f' (.exists f')) (ana/parse-ns f'))))
(defn load [repl-env provides url] (-load repl-env provides url))
(defn repl-title []
  (println "ClojureScript" (util/clojurescript-version)))
(defn repl-prompt [] (print (str ana/*cljs-ns* "=> ")))
(defn repl-read
  "Default :read hook for repl. Reads from *in* which must either be an\n  instance of LineNumberingPushbackReader or duplicate its behavior of both\n  supporting .unread and collapsing all of CR, LF, and CRLF into a single\n  \\newline. repl-read:\n    - skips whitespace, then\n      - returns request-prompt on start of line, or\n      - returns request-exit on end of stream, or\n      - reads an object from the input stream, then\n        - skips the next input character if it's end of line, then\n        - returns the object."
  ([request-prompt request-exit]
    (repl-read request-prompt request-exit *repl-opts*))
  ([request-prompt request-exit opts]
    (let [current-in *in* bind-in? (true? (:source-map-inline opts))]
      (binding [*in* (if bind-in? ((:reader opts)) *in*)]
        (or
          ({:line-start request-prompt  :stream-end request-exit}
            (skip-whitespace *in*))
          (let [input (reader/read
                        {:read-cond :allow  :features #{:cljs}}
                        *in*)]
            (readers/unread current-in (readers/read-char *in*))
            (skip-if-eol (if bind-in? current-in *in*))
            input))))))
(defn initial-prompt [quit-prompt prompt]
  (quit-prompt)
  (prompt)
  (flush))
(defn- java-loc->source
  "Convert Java class name and method symbol to source symbol, either a\n  Clojure function or Java class and method."
  [clazz method]
  (if (#{(quote invoke) (quote invokeStatic)} method)
    (let [degen (fn* [p1__21534#] (.replaceAll p1__21534# "--.*$" ""))
          [ns-name fn-name & nested] (->>
                                       (str clazz)
                                       (.split #"\$")
                                       (map demunge)
                                       (map degen))]
      (symbol
        ns-name
        (String/join "$" (into-array String (cons fn-name nested)))))
    (symbol (name clazz) (name method))))
(defn repl* [repl-env
             {:keys
              [init
               inits
               need-prompt
               quit-prompt
               prompt
               flush
               read
               eval
               print
               caught
               reader
               print-no-newline
               source-map-inline
               wrap
               repl-requires
               :cljs.repl/fast-initial-prompt?
               compiler-env
               bind-err] 
              :or
              {caught repl-caught 
               quit-prompt repl-title 
               eval eval-cljs 
               print-no-newline print 
               flush flush 
               fast-initial-prompt? false 
               read repl-read 
               bind-err true 
               print println 
               source-map-inline true 
               prompt repl-prompt 
               repl-requires
               (quote
                 [[cljs.repl
                   :refer-macros
                   [source doc find-doc apropos dir pst]]
                  [cljs.pprint :refer [pprint] :refer-macros [pp]]]) 
               reader
               (fn*
                 []
                 (readers/source-logging-push-back-reader
                   *in*
                   1
                   "")) 
               need-prompt
               (fn*
                 []
                 (if (readers/indexing-reader? *in*)
                   (== (readers/get-column-number *in*) 1)
                   (identity true)))} 
              :as opts}]
  (when (and
          (find-ns (quote clojure.tools.reader))
          (not (find-ns (quote cljs.vendor.bridge))))
    (require (quote cljs.vendor.bridge)))
  (doseq [[unknown-opt suggested-opt] (util/unknown-opts
                                        (set (keys opts))
                                        (set/union
                                          known-repl-opts
                                          cljsc/known-opts))]
    (when suggested-opt
      (println
        (str
          "WARNING: Unknown option '"
          unknown-opt
          "'. Did you mean '"
          suggested-opt
          "'?"))))
  (when (true? fast-initial-prompt?)
    (initial-prompt quit-prompt prompt))
  (let [repl-opts (-repl-options repl-env)
        repl-requires (into repl-requires (:repl-requires repl-opts))
        {:keys
         [analyze-path
          repl-verbose
          warn-on-undeclared
          special-fns
          checked-arrays
          static-fns
          fn-invoke-direct] 
         :as opts 
         :or {warn-on-undeclared true}} (merge
                                          {:def-emits-var true}
                                          (cljsc/add-implicit-options
                                            (merge-with
                                              (fn 
                                                [a b]
                                                (if (nil? b) a b))
                                              repl-opts
                                              opts
                                              {:print-no-newline
                                               print-no-newline 
                                               :flush flush 
                                               :read read 
                                               :print print 
                                               :source-map-inline
                                               source-map-inline 
                                               :prompt prompt 
                                               :reader reader 
                                               :need-prompt
                                               need-prompt 
                                               :caught caught})))
        done? (atom false)]
    (env/with-compiler-env
      (or compiler-env env/*compiler* (env/default-compiler-env opts))
      (when (:source-map opts)
        (.start
          (Thread.
            (bound-fn [] (read-source-map "cljs/core.aot.js")))))
      (binding [*repl-env* repl-env
                ana/*unchecked-if* false
                ana/*unchecked-arrays* false
                *err* (if bind-err
                        (cond->
                          *out*
                          (not (instance? PrintWriter *out*))
                          (PrintWriter.))
                        *err*)
                ana/*cljs-ns* ana/*cljs-ns*
                *cljs-verbose* repl-verbose
                ana/*cljs-warnings* (let 
                                      [warnings (opts :warnings)]
                                      (merge
                                        ana/*cljs-warnings*
                                        (if
                                          (or
                                            (true? warnings)
                                            (false? warnings))
                                          (zipmap
                                            (keys ana/*cljs-warnings*)
                                            (repeat warnings))
                                          warnings)
                                        (zipmap
                                          [:unprovided
                                           :undeclared-var
                                           :undeclared-ns
                                           :undeclared-ns-form]
                                          (repeat
                                            (if
                                              (false? warnings)
                                              false
                                              warn-on-undeclared)))
                                        {:infer-warning false}))
                ana/*checked-arrays* checked-arrays
                ana/*cljs-static-fns* static-fns
                ana/*fn-invoke-direct* (and
                                         static-fns
                                         fn-invoke-direct)
                *repl-opts* opts]
        (try
          (let [env (assoc (ana/empty-env) :context :expr)
                special-fns (merge default-special-fns special-fns)
                is-special-fn? (set (keys special-fns))
                request-prompt (Object.)
                request-exit (Object.)
                opts (comp/with-core-cljs
                       opts
                       (fn []
                         (if-let [merge-opts
                                  (:merge-opts (-setup repl-env opts))]
                           (merge opts merge-opts)
                           opts)))
                _ (when (= :after-setup fast-initial-prompt?)
                    (initial-prompt quit-prompt prompt))
                init (do
                       (evaluate-form
                         repl-env
                         env
                         ""
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list (quote set!))
                             (clojure.core/list
                               (quote
                                 cljs.core/*print-namespace-maps*))
                             (clojure.core/list (quote true))))
                         identity
                         opts)
                       (or
                         init
                         (fn*
                           []
                           (evaluate-form
                             repl-env
                             env
                             ""
                             (with-meta
                               (clojure.core/seq
                                 (clojure.core/concat
                                   (clojure.core/list (quote ns))
                                   (clojure.core/list
                                     (quote cljs.user))
                                   (clojure.core/list
                                     (clojure.core/seq
                                       (clojure.core/concat
                                         (clojure.core/list :require)
                                         repl-requires)))))
                               {:line 1  :column 1})
                             identity
                             opts))))
                maybe-load-user-file (fn*
                                       []
                                       (when-let 
                                         [user-resource
                                          (util/ns->source
                                            (quote user))]
                                         (when
                                           (=
                                             "file"
                                             (.getProtocol
                                               user-resource))
                                           (load-file
                                             repl-env
                                             (io/file user-resource)
                                             opts))))
                read-eval-print (fn 
                                  []
                                  (let 
                                    [input
                                     (binding 
                                       [*ns* (create-ns ana/*cljs-ns*)
                                        reader/resolve-symbol
                                        ana/resolve-symbol
                                        reader/*data-readers*
                                        (merge
                                          tags/*cljs-data-readers*
                                          (ana/load-data-readers))
                                        reader/*alias-map*
                                        (ana/get-aliases
                                          ana/*cljs-ns*)]
                                       (try
                                         (read
                                           request-prompt
                                           request-exit)
                                         (catch
                                           Throwable
                                           e
                                           (throw
                                             (ex-info
                                               nil
                                               {:clojure.error/phase:read-source                                                     }e)))))](or({
                                               request-exit                                request-exit                              :cljs/quitrequest-exitrequest-prompt                                 request-prompt}input)(if
                                        (and(seq?input )(is-special-fn?                                        (first
                                      input                                       )))(
                                          do((getspecial-fns                                     (firstinput))repl-env                                       envinputopts)(print                                     nil
                                          ))(let                                             [value(eval
                                             repl-envenvinput                                           opts)](try                                           (print                                          value
                                            )(catch                                         Throwablee(throw                                     (ex-info                                        nil{:clojure.error/phase                          :print-eval-result                                 }e))))))
                                             )))
                                             ](maybe-install-npm-deps                           opts)(
                                          comp/with-core-cljs                              opts(fn[](binding                                         [*repl-opts*                                         opts](try
                                              (
                                              whenanalyze-path                                       (if(vector?                                                analyze-path                                          )(run!(fn*[p1__21654#]
                                                                  (analyze-sourcep1__21654#                                             opts))analyze-path      )(analyze-sourceanalyze-pathopts          )))(when-let[main-ns
              (:main             opts)]
                (.start( Thread.(bound-fn[]
                  (ana/analyze-file        (util/ns->sourcemain-ns                  ))) )))(init )(run-initsrepl-env                   inits
                          )(maybe-load-user-file           )(catchThrowable                         e(caughterepl-envopts)))(when-let
                          [src(:watchopts                       )](.start(Thread.((ns-resolve(quoteclojure.core          )(quotebinding-conveyor-fn))(fn[
                      ](let[log-file                  (io/file
                          (util/output-directory                opts                           )"watch.log")](err-out                          (println"Watch compilation log available at:"      (strlog-file               )))(try(let[log-out (FileWriter.               log-file)](binding[*err*                   log-out*out*log-out](cljsc/watchsrc(dissocopts                  :watch)env/*compiler*done?)))
                    (catchThrowable               e(caught
                        erepl-envopts                           )))))) )))(Thread/sleep                         50)(binding[*in*(if(true?(:source-map-inline           opts))
                            *in* (reader))
                                  ](when-not                                   fast-initial-prompt?(initial-prompt                              quit-promptprompt                           ))(loop[
                                ](when-not                                 (try(identical?(read-eval-print) request-exit                           )(catchThrowable
                              e(caught                             erepl-env                               opts)nil ))(when(need-prompt)(prompt                               )(flush) 
                                    )(recur))))))) )(catchThrowable                                   t(throw(ex-info                                    "Unexpected error during REPL initialization"{:cljs.repl/error
                                      :init-failed}t
                                      )))(finally                              (reset!                                  done?true
                                  )
                                  (-tear-downrepl-env)))))))
(defn decorate-specs [specs]
  (if-let [k (some #{:reload :reload-all} specs)]
    (->>
      specs
      (remove #{k})
      (map (fn* [p1__21455#] (vary-meta p1__21455# assoc :reload k))))
    specs))
(defn repl-nil? [x] (boolean (#{"" "nil"} x)))
(defn load-stream [repl-env filename res]
  (let [env (ana/empty-env)]
    (with-open [rdr (io/reader res)]
      (doseq [form (ana/forms-seq* rdr filename)]
        (let [env (assoc env :ns (ana/get-namespace ana/*cljs-ns*))]
          (evaluate-form repl-env env filename form))))))
(clojure.core/defn dir
  "Prints a sorted directory of public vars in a namespace"
  ([&form &env ns]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/doseq))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote sym__21800__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote quote))
                      (clojure.core/list
                        (sort
                          (named-publics-vars (resolve-ns ns)))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/println))
              (clojure.core/list (quote sym__21800__auto__)))))))))
(defn- resolve-ns
  "Resolves a namespace symbol to a namespace by first checking to see if it\n  is a namespace alias."
  [ns-sym]
  (or
    (get-in
      (clojure.core/deref env/*compiler*)
      [:cljs.analyzer/namespaces ana/*cljs-ns* :requires ns-sym])
    (get-in
      (clojure.core/deref env/*compiler*)
      [:cljs.analyzer/namespaces ana/*cljs-ns* :require-macros ns-sym])
    ns-sym))
(clojure.core/defn doc
  "Prints documentation for a var or special form given its name,\n  or for a spec if given a keyword"
  ([&form &env name]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/print))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.core/*print-newline*))
                      (clojure.core/list (quote true))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list
                      (quote clojure.core/with-out-str))
                    (clojure.core/list
                      (if-let [special-name ((quote
                                               {& fn 
                                                catch try 
                                                finally try})
                                              name)]
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.repl/doc))
                            (clojure.core/list special-name)))
                        (cond
                          (special-doc-map name) (clojure.core/seq
                                                   (clojure.core/concat
                                                     (clojure.core/list
                                                       (quote
                                                         cljs.repl/print-doc))
                                                     (clojure.core/list
                                                       (clojure.core/seq
                                                         (clojure.core/concat
                                                           (clojure.core/list
                                                             (quote
                                                               quote))
                                                           (clojure.core/list
                                                             (special-doc
                                                               name)))))))
                          (repl-special-doc-map name) (clojure.core/seq
                                                        (clojure.core/concat
                                                          (clojure.core/list
                                                            (quote
                                                              cljs.repl/print-doc))
                                                          (clojure.core/list
                                                            (clojure.core/seq
                                                              (clojure.core/concat
                                                                (clojure.core/list
                                                                  (quote
                                                                    quote))
                                                                (clojure.core/list
                                                                  (repl-special-doc
                                                                    name)))))))
                          (keyword? name) (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote
                                                  cljs.repl/print-doc))
                                              (clojure.core/list
                                                (clojure.core/apply
                                                  clojure.core/hash-map
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        :spec)
                                                      (clojure.core/list
                                                        name)
                                                      (clojure.core/list
                                                        :doc)
                                                      (clojure.core/list
                                                        (clojure.core/seq
                                                          (clojure.core/concat
                                                            (clojure.core/list
                                                              (quote
                                                                cljs.spec.alpha/describe))
                                                            (clojure.core/list
                                                              name))))))))))
                          (ana-api/find-ns name) (clojure.core/seq
                                                   (clojure.core/concat
                                                     (clojure.core/list
                                                       (quote
                                                         cljs.repl/print-doc))
                                                     (clojure.core/list
                                                       (clojure.core/seq
                                                         (clojure.core/concat
                                                           (clojure.core/list
                                                             (quote
                                                               quote))
                                                           (clojure.core/list
                                                             (select-keys
                                                               (ana-api/find-ns
                                                                 name)
                                                               [:name
                                                                :doc])))))))
                          (ana-api/resolve &env name) (clojure.core/seq
                                                        (clojure.core/concat
                                                          (clojure.core/list
                                                            (quote
                                                              cljs.repl/print-doc))
                                                          (clojure.core/list
                                                            (clojure.core/seq
                                                              (clojure.core/concat
                                                                (clojure.core/list
                                                                  (quote
                                                                    quote))
                                                                (clojure.core/list
                                                                  (let 
                                                                    [var
                                                                     (ana-api/resolve
                                                                       &env
                                                                       name)
                                                                     m
                                                                     (select-keys
                                                                       var
                                                                       [:ns
                                                                        :name
                                                                        :doc
                                                                        :forms
                                                                        :arglists
                                                                        :macro
                                                                        :url])]
                                                                    (cond->
                                                                      (update-in
                                                                        m
                                                                        [:name]
                                                                        clojure.core/name)
                                                                      (:protocol-symbol
                                                                        var)
                                                                      (assoc
                                                                        :protocol
                                                                        true
                                                                        :methods
                                                                        (->>
                                                                          (get-in
                                                                            var
                                                                            [:protocol-info
                                                                             :methods])
                                                                          (map
                                                                            (fn 
                                                                              [[fname
                                                                                sigs]]
                                                                              [fname
                                                                               {:doc
                                                                                (:doc
                                                                                  (ana-api/resolve
                                                                                    &env
                                                                                    (symbol
                                                                                      (str
                                                                                        (:ns
                                                                                          var))
                                                                                      (str
                                                                                        fname)))) 
                                                                                :arglists
                                                                                (seq
                                                                                  sigs)}]))
                                                                          (into
                                                                            {}))))))))))))))))))))))))
(clojure.core/defn apropos
  "Given a regular expression or stringable thing, return a seq of all\npublic definitions in all currently-loaded namespaces that match the\nstr-or-pattern."
  ([&form &env str-or-pattern]
    (let [matches? (if (instance? Pattern str-or-pattern)
                     (fn*
                       [p1__21781#]
                       (re-find str-or-pattern (str p1__21781#)))
                     (fn*
                       [p1__21782#]
                       (.contains
                         (str p1__21782#)
                         (str str-or-pattern))))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote quote))
          (clojure.core/list
            (sort
              (mapcat
                (fn [ns]
                  (let [ns-name (str ns)]
                    (map
                      (fn*
                        [p1__21783#]
                        (symbol ns-name (str p1__21783#)))
                      (filter matches? (named-publics-vars ns)))))
                (ana-api/all-ns)))))))))
(defn repl-quit-prompt [] (println "To quit, type:" :cljs/quit))
(defn- mapped-frame
  "Given opts and a canonicalized JavaScript stacktrace frame, return the\n  ClojureScript frame."
  [{:keys [function file line column]} opts]
  (let [no-source-file? (if-not file true (.startsWith file "<"))
        rfile (when-not no-source-file?
                (io/file
                  (URL.
                    (.toURL (io/file (util/output-directory opts)))
                    file)))
        [sm {:keys [ns source-file]  :as ns-info}] (when-not
                                                     no-source-file?
                                                     ((juxt
                                                        read-source-map
                                                        ns-info)
                                                       rfile))
        [line' column' call] (if ns-info
                               (mapped-line-column-call sm line column)
                               [line column])
        name' (when (and ns-info function) function)
        file' (if no-source-file?
                file
                (string/replace
                  (.getCanonicalFile
                    (if ns-info source-file (io/file rfile)))
                  (str (System/getProperty "user.dir") File/separator)
                  ""))
        url (or
              (and ns-info (util/ns->source ns))
              (and file (io/resource file)))]
    (merge
      {:function name' 
       :call call 
       :file
       (if no-source-file?
         (str "" (when file (str " " file)))
         (io/file file')) 
       :line line' 
       :column column'}
      (when url {:url url}))))
(defn ex-str
  "Returns a string from exception data, as produced by ex-triage.\n  The first line summarizes the exception phase and location.\n  The subsequent lines describe the cause."
  [{:keys
    [:clojure.error/phase
     :clojure.error/source
     :clojure.error/line
     :clojure.error/column
     :clojure.error/symbol
     :clojure.error/class
     :clojure.error/cause
     :clojure.error/spec] 
    :as triage-data}]
  (let [spec-loaded? (some?
                       (resolve
                         (quote clojure.spec.alpha/explain-out)))
        loc (str
              (or source "REPL")
              ":"
              (or line 1)
              (if column (str ":" column) ""))
        class-name (name (or class ""))
        simple-class (if class
                       (or
                         (first (re-find #"([^.])++$" class-name))
                         class-name))
        cause-type (if (contains?
                         #{"RuntimeException" "Exception"}
                         simple-class)
                     ""
                     (str " (" simple-class ")"))]
    (case
      phase
      :read-source
      (format "Syntax error reading source at (%s).%n%s%n" loc cause)
      :macro-syntax-check
      (format
        "Syntax error macroexpanding %sat (%s).%n%s"
        (if symbol (str symbol " ") "")
        loc
        (if (and spec spec-loaded?)
          (with-out-str
            ((resolve (quote clojure.spec.alpha/explain-out))
              (if (=
                    (clojure.core/deref
                      (resolve
                        (quote clojure.spec.alpha/*explain-out*)))
                    (clojure.core/deref
                      (resolve
                        (quote clojure.spec.alpha/explain-printer))))
                (update
                  spec
                  :clojure.spec.alpha/problems
                  (fn [probs]
                    (map
                      (fn* [p1__21578#] (dissoc p1__21578# :in))
                      probs)))
                spec)))
          (format "%s%n" cause)))
      :macroexpansion
      (format
        "Unexpected error%s macroexpanding %sat (%s).%n%s%n"
        cause-type
        (if symbol (str symbol " ") "")
        loc
        cause)
      :compile-syntax-check
      (format
        "Syntax error%s compiling %sat (%s).%n%s%n"
        cause-type
        (if symbol (str symbol " ") "")
        loc
        cause)
      :compilation
      (format
        "Unexpected error%s compiling %sat (%s).%n%s%n"
        cause-type
        (if symbol (str symbol " ") "")
        loc
        cause)
      :read-eval-result
      (format
        "Error reading eval result%s at %s (%s).%n%s%n"
        cause-type
        symbol
        loc
        cause)
      :print-eval-result
      (format
        "Error printing return value%s at %s (%s).%n%s%n"
        cause-type
        symbol
        loc
        cause)
      :execution
      (if (and spec spec-loaded?)
        (format
          "Execution error - invalid arguments to %s at (%s).%n%s"
          symbol
          loc
          (with-out-str
            ((resolve (quote clojure.spec.alpha/explain-out))
              (if (=
                    (clojure.core/deref
                      (resolve
                        (quote clojure.spec.alpha/*explain-out*)))
                    (clojure.core/deref
                      (resolve
                        (quote clojure.spec.alpha/explain-printer))))
                (update
                  spec
                  :clojure.spec.alpha/problems
                  (fn [probs]
                    (map
                      (fn* [p1__21579#] (dissoc p1__21579# :in))
                      probs)))
                spec))))
        (format
          "Execution error%s at %s(%s).%n%s%n"
          cause-type
          (if symbol (str symbol " ") "")
          loc
          cause)))))
(defn eval-cljs
  "Given a REPL evaluation environment, an analysis environment, and a\n   form, evaluate the form and return the result. The result is always the value\n   represented as a string."
  ([repl-env env form] (eval-cljs repl-env env form *repl-opts*))
  ([repl-env env form opts]
    (evaluate-form
      repl-env
      (assoc env :ns (ana/get-namespace ana/*cljs-ns*))
      ""
      form
      ((or (:wrap opts) wrap-fn) form)
      opts)))
(defn read-source-map
  "Return the source map for the JavaScript source file."
  [f]
  (when-let [smf (util/file-or-resource (str f ".map"))]
    (let [ns (if (= f "cljs/core.aot.js")
               (quote cljs.core)
               (some-> (js-src->cljs-src f) ana/parse-ns :ns))]
      (when ns
        (as->
          (clojure.core/deref env/*compiler*)
          compiler-env
          (let [t (util/last-modified smf)]
            (if (or
                  (and
                    (= ns (quote cljs.core))
                    (nil?
                      (get-in
                        compiler-env
                        [:cljs.repl/source-maps ns])))
                  (and
                    (not= ns (quote cljs.core))
                    (>
                      t
                      (get-in
                        compiler-env
                        [:cljs.repl/source-maps ns :last-modified]
                        0))))
              (swap!
                env/*compiler*
                assoc-in
                [:cljs.repl/source-maps ns]
                {:last-modified t 
                 :source-map
                 (sm/decode
                   (json/read-str (slurp smf) :key-fn keyword))})
              compiler-env))
          (get-in
            compiler-env
            [:cljs.repl/source-maps ns :source-map]))))))
(defn repl-options [repl-env] (-repl-options repl-env))
(defn- load-dependencies
  "Compile and load the given `requires` and return the compiled sources."
  ([repl-env requires] (load-dependencies repl-env requires nil))
  ([repl-env requires opts]
    (doall
      (mapcat
        (fn* [p1__21329#] (load-namespace repl-env p1__21329# opts))
        (distinct requires)))))
(defn- file-name
  "Helper to get just the file name part of a path or nil"
  [full-path]
  (when full-path
    (try (.getName (java.io.File. full-path)) (catch Throwable t))))
(defn setup [repl-env opts] (-setup repl-env opts))
(defn- init-wrap-fn [form]
  (cond
    (and
      (seq? form)
      (#{(quote import)
         (quote require-macros)
         (quote ns)
         (quote use-macros)
         (quote use)
         (quote require)
         (quote refer-clojure)}
        (first form))) identity
    ((quote #{*2 *1 *e *3}) form) (fn 
                                    [x]
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote cljs.core.pr-str))
                                        (clojure.core/list x))))
    :else (fn [x]
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core.pr-str))
                (clojure.core/list x))))))
(clojure.core/defn source
  "Prints the source code for the given symbol, if it can find it.\n  This requires that the symbol resolve to a Var defined in a\n  namespace for which the .cljs is in the classpath.\n\n  Example: (source filter)"
  ([&form &env n]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/println))
        (clojure.core/list
          (or (source-fn &env n) (str "Source not found")))))))
(defn- root-resource
  "Returns the root directory path for a lib"
  {:tag String}
  [lib]
  (str \/ (.. (name lib) (replace \- \_) (replace \. \/))))
(defn maybe-install-npm-deps [opts]
  (when (:install-deps opts)
    (cljsc/check-npm-deps opts)
    (swap!
      env/*compiler*
      update-in
      [:npm-deps-installed?]
      (fn [installed?]
        (if-not installed?
          (cljsc/maybe-install-node-deps! opts)
          installed?)))))
(defn repl-caught [e repl-env opts]
  (if (and
        (instance? IExceptionInfo e)
        (#{:js-eval-error :js-eval-exception} (:type (ex-data e))))
    (let [{:keys [type repl-env error form js]} (ex-data e)]
      (case
        type
        :js-eval-error
        (display-error repl-env error form opts)
        :js-eval-exception
        (display-error
          repl-env
          error
          form
          (if (:repl-verbose opts)
            (fn* [] (prn "Error evaluating:" form :as js))
            (constantly nil))
          opts)))
    (binding [*out* *err*]
      (print (-> e Throwable->map ex-triage ex-str))
      (flush))))
(defn tear-down [repl-env] (-tear-down repl-env))
(defn- repl-special-doc [name-symbol]
  (assoc
    (repl-special-doc-map name-symbol)
    :name
    name-symbol
    :repl-special-function
    true))
(defn source-fn
  "Returns a string of the source code for the given symbol, if it can\n  find it.  This requires that the symbol resolve to a Var defined in\n  a namespace for which the .clj is in the classpath.  Returns nil if\n  it can't find the source.  For most REPL usage, 'source' is more\n  convenient.\n\n  Example: (source-fn 'filter)"
  [env x]
  (when-let [v (ana-api/resolve env x)]
    (when-let [filepath (:file v)]
      (let [f (io/file filepath)
            f (if (.exists f) f (io/resource filepath))]
        (when f
          (with-open [pbr (PushbackReader. (io/reader f))]
            (let [rdr (readers/source-logging-push-back-reader pbr)]
              (dotimes [_ (dec (:line v))] (readers/read-line rdr))
              (binding [reader/*alias-map* identity
                        reader/*data-readers* (merge
                                                tags/*cljs-data-readers*
                                                (ana/load-data-readers))]
                (-> (reader/read
                      {:read-cond :allow  :features #{:cljs}}
                      rdr)
                 meta
                 :source)))))))))
(defn skip-whitespace
  "Skips whitespace characters on stream s. Returns :line-start, :stream-end,\n  or :body to indicate the relative location of the next character on s.\n  Interprets comma as whitespace and semicolon as comment to end of line.\n  Does not interpret #! as comment to end of line because only one\n  character of lookahead is available. The stream must either be an\n  instance of LineNumberingPushbackReader or duplicate its behavior of both\n  supporting .unread and collapsing all of CR, LF, and CRLF to a single\n  \\newline."
  [s]
  (loop [c (readers/read-char s)]
    (case
      c
      \newline
      :line-start
      nil
      :stream-end
      \;
      (do (readers/read-line s) :line-start)
      (if (or (Character/isWhitespace c) (identical? c \,))
        (recur (readers/read-char s))
        (do (readers/unread s c) :body)))))
(defn ex-triage
  "Returns an analysis of the phase, error, cause, and location of an error that occurred\n  based on Throwable data, as returned by Throwable->map. All attributes other than phase\n  are optional:\n    :clojure.error/phase - keyword phase indicator, one of:\n      :read-source :compile-syntax-check :compilation :macro-syntax-check :macroexpansion\n      :execution :read-eval-result :print-eval-result\n    :clojure.error/source - file name (no path)\n    :clojure.error/line - integer line number\n    :clojure.error/column - integer column number\n    :clojure.error/symbol - symbol being expanded/compiled/invoked\n    :clojure.error/class - cause exception class symbol\n    :clojure.error/cause - cause exception message\n    :clojure.error/spec - explain-data for spec error"
  [datafied-throwable]
  (let [{:keys [via trace phase]  :or {phase :execution}} datafied-throwable
        {:keys [type message data]} (last via)
        {:keys
         [:clojure.spec.alpha/problems
          :clojure.spec.alpha/fn
          :clojure.spec.test.alpha/caller]} data
        {:keys [:clojure.error/source]  :as top-data} (:data
                                                        (first via))]
    (assoc
      (case
        phase
        :read-source
        (let [{:keys [:clojure.error/line :clojure.error/column]} data]
          (cond->
            (merge (-> via second :data) top-data)
            source
            (assoc :clojure.error/source (file-name source))
            (#{"NO_SOURCE_PATH" "NO_SOURCE_FILE"} source)
            (dissoc :clojure.error/source)
            message
            (assoc :clojure.error/cause message)))
        (:compile-syntax-check
          :compilation
          :macro-syntax-check
          :macroexpansion)
        (cond->
          top-data
          source
          (assoc :clojure.error/source (file-name source))
          (#{"NO_SOURCE_PATH" "NO_SOURCE_FILE"} source)
          (dissoc :clojure.error/source)
          type
          (assoc :clojure.error/class type)
          message
          (assoc :clojure.error/cause message)
          problems
          (assoc :clojure.error/spec data))
        (:read-eval-result :print-eval-result)
        (let [[source method file line] (-> trace first)]
          (cond->
            top-data
            line
            (assoc :clojure.error/line line)
            file
            (assoc :clojure.error/source file)
            (and source method)
            (assoc
              :clojure.error/symbol
              (java-loc->source source method))
            type
            (assoc :clojure.error/class type)
            message
            (assoc :clojure.error/cause message)))
        :execution
        (let [[source method file line] (->>
                                          trace
                                          (drop-while
                                            (fn*
                                              [p1__21541#]
                                              (core-class?
                                                (name
                                                  (first
                                                    p1__21541#)))))
                                          first)
              file (first
                     (remove
                       (fn*
                         [p1__21542#]
                         (or
                           (nil? p1__21542#)
                           (#{"NO_SOURCE_PATH" "NO_SOURCE_FILE"}
                             p1__21542#)))
                       [(:file caller) file]))
              err-line (or (:line caller) line)]
          (cond->
            {:clojure.error/classtype}err-line       (assoc:clojure.error/lineerr-line)message(assoc :clojure.error/cause  message
            )(orfn (andsourcemethod))(assoc:clojure.error/symbol (orfn(java-loc->sourcesource        method
              )))file(assoc:clojure.error/source  file)problems(assoc:clojure.error/specdata            ))))
            :clojure.error/phasephase)))
(defn- env->opts
  "Returns a hash-map containing all of the entries in [repl-env], translating\n:working-dir to :output-dir."
  ([repl-env] (env->opts repl-env nil))
  ([repl-env opts]
    (-> (into {} repl-env)
     (assoc
       :optimizations
       (or (:optimizations opts) (get repl-env :optimizations :none)))
     (assoc
       :output-dir
       (or (:output-dir opts) (get repl-env :working-dir ".repl"))))))
(defn mapped-stacktrace
  "Given a vector representing the canonicalized JavaScript stacktrace\n   return the ClojureScript stacktrace. The canonical stacktrace must be\n   in the form:\n\n    [{:file \n      :function \n      :line \n      :column }*]\n\n   :file must be a URL path (without protocol) relative to :output-dir or a\n   identifier delimited by angle brackets. The returned mapped stacktrace will\n   also contain :url entries to the original sources if it can be determined\n   from the classpath."
  ([stacktrace] (mapped-stacktrace stacktrace nil))
  ([stacktrace opts]
    (vec
      (let [mapped-frames (map
                            (memoize
                              (fn*
                                [p1__21366#]
                                (mapped-frame p1__21366# opts)))
                            stacktrace)]
        (map
          (fn*
            [p1__21367# p2__21368#]
            (merge-with
              (fn [munged-fn-name unmunged-call-name]
                (if (=
                      munged-fn-name
                      (string/replace
                        (cljs.compiler/munge unmunged-call-name)
                        "."
                        "$"))
                  unmunged-call-name
                  munged-fn-name))
              p1__21367#
              p2__21368#))
          (map
            (fn* [p1__21369#] (dissoc p1__21369# :call))
            mapped-frames)
          (concat
            (rest
              (map
                (fn*
                  [p1__21370#]
                  (if (:call p1__21370#)
                    (hash-map :function (:call p1__21370#))
                    {}))
                mapped-frames))
            [{}]))))))
(defn skip-if-eol
  "If the next character on stream s is a newline, skips it, otherwise\n  leaves the stream untouched. Returns :line-start, :stream-end, or :body\n  to indicate the relative location of the next character on s. The stream\n  must either be an instance of LineNumberingPushbackReader or duplicate\n  its behavior of both supporting .unread and collapsing all of CR, LF, and\n  CRLF to a single \\newline."
  [s]
  (let [c (readers/read-char s)]
    (case
      c
      \newline
      :line-start
      nil
      :stream-end
      (do (readers/unread s c) :body))))
(defn- bytes-to-base64-str
  "Convert a byte array into a base-64 encoded string."
  [bytes]
  (.encodeToString (Base64/getEncoder) bytes))
(defn load-file
  ([repl-env f] (load-file repl-env f *repl-opts*))
  ([repl-env f opts]
    (if (:output-dir opts)
      (let [src (cond
                  (util/url? f) f
                  (.exists (io/file f)) (io/file f)
                  :else (io/resource f))
            compiled (binding [ana/*reload-macros* true]
                       (cljsc/handle-js-modules
                         opts
                         (deps/dependency-order
                           (cljsc/add-dependency-sources
                             [(ana/parse-ns src)]
                             opts))
                         env/*compiler*)
                       (cljsc/compile
                         src
                         (assoc
                           opts
                           :output-file
                           (cljsc/src-file->target-file src)
                           :force
                           true
                           :mode
                           :interactive)))]
        (when-let [ns (and
                        (:source-map opts)
                        (first (:provides compiled)))]
          (spit
            (io/file
              (io/file (util/output-directory opts))
              (util/ns->relpath ns (util/ext (:source-url compiled))))
            (slurp src)))
        (let [sources (load-dependencies
                        repl-env
                        (:requires compiled)
                        opts)]
          (load-cljs-loader repl-env (conj sources compiled) opts))
        (-evaluate repl-env f 1 (cljsc/add-dep-string opts compiled))
        (-evaluate
          repl-env
          f
          1
          (cljsc/src-file->goog-require
            src
            {:wrap true 
             :reload true 
             :macros-ns (:macros-ns compiled)})))
      (binding [ana/*cljs-ns* ana/*cljs-ns*]
        (let [res (if (= File/separatorChar (first f))
                    f
                    (io/resource f))]
          (assert res (str "Can't find " f " in classpath"))
          (load-stream repl-env f res))))))
(defn- display-error
  ([repl-env ret form opts]
    (display-error repl-env ret form (constantly nil) opts))
  ([repl-env ret form f opts]
    (err-out
      (f)
      (when-let [value (:value ret)] (println value))
      (when-let [st (:stacktrace ret)]
        (if (and
              (true? (:source-map opts))
              (satisfies? IParseStacktrace repl-env))
          (let [cst (try
                      (-parse-stacktrace repl-env st ret opts)
                      (catch
                        Throwable
                        e
                        (when (:repl-verbose opts)
                          (println "Failed to canonicalize stacktrace")
                          (println e))))]
            (if (vector? cst)
              (if (satisfies? IPrintStacktrace repl-env)
                (-print-stacktrace repl-env cst ret opts)
                (print-mapped-stacktrace cst opts))
              (println st)))
          (println st))))))
(defn- special-doc [name-symbol]
  (assoc
    (or (special-doc-map name-symbol) (meta (resolve name-symbol)))
    :name
    name-symbol
    :special-form
    true))
(clojure.core/defn pst
  ([&form &env]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.repl/pst))
        (clojure.core/list (quote clojure.core/*e)))))
  ([&form &env e]
    (let [{:keys [repl-env]  :as env} &env]
      (when (and e repl-env)
        (when-let [ret (if (satisfies? IGetError repl-env)
                         (-get-error repl-env e env *repl-opts*)
                         (edn/read-string
                           (evaluate-form
                             repl-env
                             env
                             ""
                             (clojure.core/seq
                               (clojure.core/concat
                                 (clojure.core/list
                                   (quote clojure.core/when))
                                 (clojure.core/list e)
                                 (clojure.core/list
                                   (clojure.core/seq
                                     (clojure.core/concat
                                       (clojure.core/list
                                         (quote clojure.core/pr-str))
                                       (clojure.core/list
                                         (clojure.core/apply
                                           clojure.core/hash-map
                                           (clojure.core/seq
                                             (clojure.core/concat
                                               (clojure.core/list
                                                 :value)
                                               (clojure.core/list
                                                 (clojure.core/seq
                                                   (clojure.core/concat
                                                     (clojure.core/list
                                                       (quote
                                                         clojure.core/str))
                                                     (clojure.core/list
                                                       e))))
                                               (clojure.core/list
                                                 :stacktrace)
                                               (clojure.core/list
                                                 (clojure.core/seq
                                                   (clojure.core/concat
                                                     (clojure.core/list
                                                       (quote .-stack))
                                                     (clojure.core/list
                                                       e))))))))))))))))]
          (display-error
            repl-env
            (if (satisfies? IParseError repl-env)
              (-parse-error repl-env ret *repl-opts*)
              ret)
            nil
            *repl-opts*))))))
(defn run-inits [renv inits]
  (doseq [{:keys [type]  :as init} inits]
    (case
      type
      :init-forms
      (doseq [form (:forms init)]
        (eval-cljs renv (ana/empty-env) form))
      :eval-forms
      (binding [*repl-opts* (merge
                              *repl-opts*
                              {:def-emits-var true 
                               :wrap init-wrap-fn})]
        (doseq [form (:forms init)]
          (let [value (eval-cljs
                        renv
                        (ana/empty-env)
                        form
                        *repl-opts*)]
            (when-not (repl-nil? value) (println value)))))
      :init-script
      (let [script (:script init)]
        (load-stream renv (util/get-name script) script)))))
(defn load-namespace
  "Load a namespace and all of its dependencies into the evaluation environment.\n  The environment is responsible for ensuring that each namespace is\n  loaded once and only once. Returns the compiled sources."
  ([repl-env ns] (load-namespace repl-env ns nil))
  ([repl-env ns opts]
    (let [ns (if (and (seq? ns) (= (first ns) (quote quote)))
               (second ns)
               ns)
          sources (seq
                    (when-not (ana/node-module-dep? ns)
                      (let [input (ns->input ns opts)]
                        (if (compilable? input)
                          (->>
                            (cljsc/compile-inputs
                              [input]
                              (merge (env->opts repl-env) opts))
                            (remove (comp #{["goog"]} :provides)))
                          (map
                            (fn*
                              [p1__21324#]
                              (cljsc/source-on-disk opts p1__21324#))
                            (cljsc/add-js-sources [input] opts))))))]
      (when (:repl-verbose opts)
        (println
          (str "load-namespace " ns " , compiled:")
          (map :provides sources)))
      (load-sources repl-env sources opts)
      sources)))
(defn add-url [ijs]
  (cond->
    ijs
    (not (contains? ijs :url))
    (assoc :url (io/resource (:file ijs)))))
(defn ns->input [ns opts]
  (or
    (some-> (util/ns->source ns) (ana/parse-ns opts))
    (some->
      (get-in
        (clojure.core/deref env/*compiler*)
        [:js-dependency-index (str ns)])
      add-url)
    (some-> (deps/find-classpath-lib ns))
    (throw
      (ex-info
        (str ns " does not exist")
        {:cljs.repl/error:invalid-ns}))))
(defn file-display [file {:keys [output-dir temp-output-dir?]}]
  (if temp-output-dir?
    (let [canonicalize (fn [file] (.getCanonicalPath (io/file file)))
          can-file (canonicalize file)
          can-out (canonicalize output-dir)]
      (if (.startsWith can-file can-out)
        (subs can-file (inc (count can-out)))
        (subs
          can-file
          (inc (.lastIndexOf can-file java.io.File/separator)))))
    file))
(defn- mapped-line-column-call
  "Given a cljs.source-map source map data structure map a generated line\n   and column back to the original line, column, and function called."
  [source-map line column]
  (let [default [line column nil]]
    (if-let [columns (get source-map (dec line))]
      (vec
        (map
          (fn* [p1__21342# p2__21343#] (p1__21342# p2__21343#))
          [inc inc identity]
          (map
            (last
              (or
                (get
                  columns
                  (last
                    (filter
                      (fn* [p1__21344#] (<= p1__21344# (dec column)))
                      (sort (keys columns)))))
                (second (first columns))))
            [:line :col :name])))
      default)))
(defn- wrap-fn [form]
  (cond
    (and
      (seq? form)
      (#{(quote import)
         (quote require-macros)
         (quote ns)
         (quote use-macros)
         (quote use)
         (quote require)
         (quote refer-clojure)}
        (first form))) identity
    ((quote #{*2 *1 *e *3}) form) (fn 
                                    [x]
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote cljs.core.pr-str))
                                        (clojure.core/list x))))
    :else (fn [x]
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote try))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core.pr-str))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/let))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote ret__21439__auto__))
                                    (clojure.core/list x)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote set!))
                                  (clojure.core/list
                                    (quote clojure.core/*3))
                                  (clojure.core/list
                                    (quote clojure.core/*2)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote set!))
                                  (clojure.core/list
                                    (quote clojure.core/*2))
                                  (clojure.core/list
                                    (quote clojure.core/*1)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote set!))
                                  (clojure.core/list
                                    (quote clojure.core/*1))
                                  (clojure.core/list
                                    (quote ret__21439__auto__)))))
                            (clojure.core/list
                              (quote ret__21439__auto__))))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote catch))
                      (clojure.core/list :default)
                      (clojure.core/list (quote e__21440__auto__))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote set!))
                            (clojure.core/list (quote clojure.core/*e))
                            (clojure.core/list
                              (quote e__21440__auto__)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote throw))
                            (clojure.core/list
                              (quote e__21440__auto__)))))))))))))
(defn- root-directory
  "Returns the root resource path for a lib"
  [lib]
  (let [d (root-resource lib)] (subs d 0 (.lastIndexOf d "/"))))
(clojure.core/defn find-doc
  "Prints documentation for any var whose documentation or name\n contains a match for re-string-or-pattern"
  ([&form &env re-string-or-pattern]
    (let [re (re-pattern re-string-or-pattern)
          ms (concat
               (mapcat
                 (fn [ns]
                   (map
                     (fn [m]
                       (update-in
                         (select-keys
                           m
                           [:ns
                            :name
                            :doc
                            :forms
                            :arglists
                            :macro
                            :url])
                         [:name]
                         (fn*
                           [p1__21736#]
                           (if-not (nil? p1__21736#)
                             (clojure.core/name p1__21736#)
                             p1__21736#))))
                     (sort-by :name (vals (ana-api/ns-interns ns)))))
                 (ana-api/all-ns))
               (map
                 (fn*
                   [p1__21737#]
                   (select-keys
                     (ana-api/find-ns p1__21737#)
                     [:name :doc]))
                 (ana-api/all-ns))
               (map special-doc (keys special-doc-map)))
          ms (for
               [m
                ms
                :when
                (and
                  (:doc m)
                  (or
                    (re-find (re-matcher re (:doc m)))
                    (re-find (re-matcher re (str (:name m))))))]
               m)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/doseq))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote m__21738__auto__))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote quote))
                        (clojure.core/list ms))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.repl/print-doc))
                (clojure.core/list (quote m__21738__auto__))))))))))
(defn analyze-source
  "Given a source directory, analyzes all .cljs files. Used to populate\n  (:cljs.analyzer/namespaces compiler-env) so as to support code reflection."
  ([src-dir] (analyze-source src-dir nil))
  ([src-dir opts]
    (if-let [src-dir (and (not (empty? src-dir)) (File. src-dir))]
      (doseq [file (comp/cljs-files-in src-dir)]
        (ana/analyze-file
          (str "file://" (.getAbsolutePath file))
          opts)))))
(defn- named-publics-vars
  "Gets the public vars in a namespace that are not anonymous."
  [ns]
  (->>
    (ana-api/ns-publics ns)
    (remove (comp :anonymous val))
    (map key)))
(defn- load-path->cp-path [path]
  (let [src (if (= File/separatorChar (first path))
              path
              (str (root-directory ana/*cljs-ns*) \/ path))
        src (.substring src 1)]
    (or
      (io/resource (str src ".cljs"))
      (io/resource (str src ".cljc")))))
(defn print-mapped-stacktrace
  "Given a vector representing the canonicalized JavaScript stacktrace\n   print the ClojureScript stacktrace. See mapped-stacktrace."
  ([stacktrace] (print-mapped-stacktrace stacktrace *repl-opts*))
  ([stacktrace opts]
    (doseq [{:keys [function file line column]} (mapped-stacktrace
                                                  stacktrace
                                                  opts)]
      (err-out
        (println
          "\t"
          (str
            (when function (str function " "))
            "("
            (file-display file opts)
            (when line (str ":" line))
            (when column (str ":" column))
            ")"))))))
(defn evaluate-form
  "Evaluate a ClojureScript form in the JavaScript environment. Returns a\n  string which is the ClojureScript return value. This string may or may\n  not be readable by the Clojure reader."
  ([repl-env env filename form]
    (evaluate-form repl-env env filename form identity))
  ([repl-env env filename form wrap]
    (evaluate-form repl-env env filename form wrap *repl-opts*))
  ([repl-env env filename form wrap opts]
    (binding [ana/*cljs-file* filename]
      (let [env (merge
                  env
                  {:root-source-info
                   {:source-type :fragment  :source-form form} 
                   :repl-env repl-env})
            def-emits-var (:def-emits-var opts)
            backup-comp (clojure.core/deref env/*compiler*)
            ->ast (fn [form]
                    (binding [ana/*analyze-deps* false]
                      (ana/analyze
                        (assoc env :def-emits-var def-emits-var)
                        (wrap form)
                        nil
                        opts)))
            ast (->ast form)
            ast (if-not (#{:ns* :ns} (:op ast))
                  ast
                  (let [ijs (ana/parse-ns [form])]
                    (cljsc/handle-js-modules
                      opts
                      (deps/dependency-order
                        (cljsc/add-dependency-sources [ijs] opts))
                      env/*compiler*)
                    (binding [ana/*check-alias-dupes* false]
                      (ana/no-warn (->ast form)))))
            wrap-js (if (:source-map repl-env)
                      (binding [comp/*source-map-data*
                                (atom
                                  {:source-map (sorted-map) 
                                   :gen-line 0})
                                comp/*source-map-data-gen-col*
                                (AtomicLong.)]
                        (let [js (comp/emit-str ast)
                              t (System/currentTimeMillis)]
                          (str
                            js
                            "\n//# sourceURL=repl-"
                            t
                            ".js"
                            "\n//# sourceMappingURL=data:application/json;base64,"
                            (bytes-to-base64-str
                              (.getBytes
                                (sm/encode
                                  {(str "repl-" t ".cljs")
                                   (:source-map
                                     (clojure.core/deref
                                       comp/*source-map-data*))}
                                  {:lines
                                   (+
                                     (:gen-line
                                       (clojure.core/deref
                                         comp/*source-map-data*))
                                     3) 
                                   :file (str "repl-" t ".js") 
                                   :sources-content
                                   [(or
                                      (:source (meta form))
                                      (with-out-str (pr form)))]})
                                "UTF-8")))))
                      (comp/emit-str ast))]
        (when (#{:ns* :ns} (:op ast))
          (let [ast (try
                      (ana/no-warn (ana/analyze env form nil opts))
                      (catch
                        Exception
                        e
                        (reset! env/*compiler* backup-comp)
                        (throw e)))
                sources (load-dependencies
                          repl-env
                          (into
                            (vals (:requires ast))
                            (distinct (vals (:uses ast))))
                          opts)]
            (load-cljs-loader repl-env sources opts)))
        (when *cljs-verbose* (err-out (println wrap-js)))
        (let [ret (-evaluate
                    repl-env
                    filename
                    (:line (meta form))
                    wrap-js)]
          (case
            (:status ret)
            :error
            (throw
              (ex-info
                (:value ret)
                {:type :js-eval-error 
                 :error ret 
                 :repl-env repl-env 
                 :form form}))
            :exception
            (throw
              (ex-info
                (:value ret)
                {:type :js-eval-exception 
                 :error ret 
                 :repl-env repl-env 
                 :form form 
                 :js wrap-js}))
            :success
            (:value ret)))))))
(defn repl
  "Generic, reusable, read-eval-print loop. By default, reads from *in* using\n  a c.t.r.reader-types/source-logging-push-back-reader,\n  writes to *out*, and prints exception summaries to *err*. If you use the\n  default :read hook, *in* must either be an instance of\n  c.t.r.reader-types/PushbackReader or duplicate its behavior of both supporting\n  unread and collapsing CR, LF, and CRLF into a single \\newline. Options\n  are sequential keyword-value pairs. The first argument is the JavaScript\n  evaluation environment, the second argument is an extended version of the\n  standard ClojureScript compiler options. In addition to ClojureScript compiler\n  build options it also take a set of options similar to clojure.main/repl with\n  adjustments for ClojureScript evalution and compilation model:\n\n  Available clojure.main/repl style options and their defaults:\n\n     - :init, function of no arguments, initialization hook called with\n       bindings for set!-able vars in place.\n       default: #()\n\n     - :need-prompt, function of no arguments, called before each\n       read-eval-print except the first, the user will be prompted if it\n       returns true.\n       default: #(if (c.t.r.readers-types/indexing-reader? *in*)\n                   (== (c.t.r.reader-types/get-column-number *in*) 1)\n                   (identity true))\n\n     - :prompt, function of no arguments, prompts for more input.\n       default: repl-prompt\n\n     - :flush, function of no arguments, flushes output\n       default: flush\n\n     - :read, function of two arguments, reads from *in*:\n         - returns its first argument to request a fresh prompt\n           - depending on need-prompt, this may cause the repl to prompt\n             before reading again\n         - returns its second argument to request an exit from the repl\n         - else returns the next object read from the input stream\n       default: repl-read\n\n     - :eval, function of one argument, returns the evaluation of its\n       argument. The eval function must take repl-env, the JavaScript evaluation\n       environment, env, the ClojureScript analysis environment, the form\n       and opts, the standard ClojureScript REPL/compiler options.\n       default: eval\n\n     - :print, function of one argument, prints its argument to the output\n       default: println\n\n     - :caught, function of three arguments, a throwable, called when\n       read, eval, or print throws an exception or error default. The second\n       argument is the JavaScript evaluation environment this permits context\n       sensitive handling if necessary. The third argument is opts, the standard\n       ClojureScript REPL/compiler options. In the case of errors or exception\n       in the JavaScript target, these will be thrown as\n       clojure.lang.IExceptionInfo instances.\n       default: repl-caught\n\n     - :reader, the c.t.r reader to use.\n       default: c.t.r.reader-types/source-logging-push-back-reader\n\n     - :print-no-newline, print without a newline.\n       default: print\n\n     - :source-map-inline, whether inline source maps should be enabled. Most\n       useful in browser context. Implies using a fresh reader for each form.\n       default: true"
  [repl-env & opts]
  (assert
    (even? (count opts))
    "Arguments after repl-env must be interleaved key value pairs")
  (repl* repl-env (apply hash-map opts)))
(defn- load-sources
  "Load the compiled `sources` into the REPL."
  [repl-env sources opts]
  (if (:output-dir opts)
    (let [sb (StringBuffer.)]
      (doseq [source sources]
        (with-open [rdr (io/reader (:url source))]
          (.append sb (cljsc/add-dep-string opts source))))
      (when (:repl-verbose opts) (println (.toString sb)))
      (-evaluate repl-env "" 1 (.toString sb)))
    (doseq [{:keys [url provides]} sources]
      (-load repl-env provides url))))
(defn evaluate [repl-env filename line js]
  (-evaluate repl-env filename line js))
(defn- load-cljs-loader
  "Compile and load the cljs.loader namespace if it's present in `sources`."
  [repl-env sources opts]
  (when-let [source (first
                      (filter
                        (fn*
                          [p1__21319#]
                          (= (:ns p1__21319#) (quote cljs.loader)))
                        sources))]
    (cljsc/compile-loader sources opts)
    (load-sources repl-env [source] opts)))
(defn compilable? [input] (contains? input :source-file))
(defn js-src->cljs-src
  "Map a JavaScript output file back to the original ClojureScript source\n   file (.cljs or .cljc)."
  [f]
  (let [f (io/file f)
        dir (.getParentFile f)
        base-name (string/replace (.getName f) ".js" "")
        cljsf (io/file dir (str base-name ".cljs"))]
    (if (.exists cljsf)
      cljsf
      (let [cljcf (io/file dir (str base-name ".cljc"))]
        (if (.exists cljcf) cljcf)))))
(defn- core-class? [class-name]
  (and
    (not (nil? class-name))
    (or
      (.startsWith class-name "clojure.lang.")
      (contains?
        core-namespaces
        (second (re-find #"^([^$]+)\$" class-name))))))
(defn demunge
  "Given a string representation of a fn class,\n  as in a stack trace element, returns a readable version."
  [fn-name]
  (clojure.lang.Compiler/demunge fn-name))
cljs.source-map 427/570 (74.9%)
(defn seg->map
  "Take a source map segment represented as a vector\n   and return a map."
  [seg source-map]
  (let [[gcol source line col name] seg]
    {:gcol gcol 
     :source (nth (:sources source-map) source) 
     :line line 
     :col col 
     :name
     (when-let [name (-> seg meta :name)]
       (nth (:names source-map) name))}))
(defn seg-combine
  "Combine a source map segment vector and a relative\n   source map segment vector and combine them to get\n   an absolute segment posititon information as a vector."
  [seg relseg]
  (let [[gcol source line col name] seg
        [rgcol rsource rline rcol rname] relseg
        nseg [(+ gcol rgcol)
              (+ (or source 0) rsource)
              (+ (or line 0) rline)
              (+ (or col 0) rcol)
              (+ (or name 0) rname)]]
    (if name (with-meta nseg {:name (+ name rname)}) nseg)))
(defn update-reverse-result
  "Helper for decode-reverse. Take a source map and update it\n  based on a segment map."
  [result segmap gline]
  (let [{:keys [gcol source line col name]} segmap
        d {:gline gline  :gcol gcol}
        d (if name (assoc d :name name) d)]
    (update-in
      result
      [source]
      (fnil
        (fn [m]
          (update-in
            m
            [line]
            (fnil
              (fn [m]
                (update-in m [col] (fnil (fn [v] (conj v d)) [])))
              (sorted-map))))
        (sorted-map)))))
(defn indexed-sources
  "Take a seq of source file names and return a map from\n   file number to integer index."
  [sources]
  (->>
    sources
    (map-indexed (fn [a b] [a b]))
    (reduce (fn [m [i v]] (assoc m v i)) {})))
(defn lines->segs
  "Take a nested sorted map encoding line and column information\n   for a file and return a vector of vectors of encoded segments.\n   Each vector represents a line, and the internal vectors are segments\n   representing the contents of the line."
  [lines]
  (let [relseg (atom [0 0 0 0 0])]
    (reduce
      (fn [segs cols]
        (swap!
          relseg
          (fn [[_ source line col name]] [0 source line col name]))
        (conj
          segs
          (reduce
            (fn [cols [gcol sidx line col name :as seg]]
              (let [offset (map - seg (clojure.core/deref relseg))]
                (swap!
                  relseg
                  (fn [[_ _ _ _ lname]] [gcol
                                         sidx
                                         line
                                         col
                                         (or name lname)]))
                (conj cols (base64-vlq/encode offset))))
            []
            cols)))
      []
      lines)))
(defn source-compare
  "Take a seq of source file names and return a comparator\n   that can be used to construct a sorted map."
  [sources]
  (let [sources (indexed-sources sources)]
    (fn [a b] (compare (sources a) (sources b)))))
(defn decode-reverse
  "Convert a v3 source map JSON object into a nested sorted map\n   organized as file, line, and column. Note this source map\n   maps from *original* source location to generated source location."
  ([source-map] (decode-reverse (:mappings source-map) source-map))
  ([mappings source-map]
    (let [{:keys [sources]} source-map
          relseg-init [0 0 0 0 0]
          lines (seq (string/split mappings #";"))]
      (loop [gline 0
             lines lines
             relseg relseg-init
             result (sorted-map-by (source-compare sources))]
        (if lines
          (let [line (first lines)
                [result relseg] (if
                                  (string/blank? line)
                                  [result relseg]
                                  (let 
                                    [segs
                                     (seq (string/split line #","))]
                                    (loop 
                                      [segs segs
                                       relseg relseg
                                       result result]
                                      (if
                                        segs
                                        (let 
                                          [seg (first segs)
                                           nrelseg
                                           (seg-combine
                                             (base64-vlq/decode seg)
                                             relseg)]
                                          (recur
                                            (next segs)
                                            nrelseg
                                            (update-reverse-result
                                              result
                                              (seg->map
                                                nrelseg
                                                source-map)
                                              gline)))
                                        [result relseg]))))]
            (recur (inc gline) (next lines) (assoc relseg 0 0) result))
          result)))))
(defn merge-source-maps
  "Merge an internal source map representation of a single\n   ClojureScript file mapping original to generated with a\n   second source map mapping original JS to generated JS.\n   The is to support source maps that work through multiple\n   compilation steps like Google Closure optimization passes."
  [cljs-map js-map]
  (loop [line-map-seq (seq cljs-map) new-lines (sorted-map)]
    (if line-map-seq
      (let [[line col-map] (first line-map-seq)
            new-cols (loop [col-map-seq (seq col-map)
                            new-cols (sorted-map)]
                       (if col-map-seq
                         (let [[col infos] (first col-map-seq)]
                           (recur
                             (next col-map-seq)
                             (assoc
                               new-cols
                               col
                               (reduce
                                 (fn 
                                   [v {:keys [gline gcol]}]
                                   (into
                                     v
                                     (get-in js-map [gline gcol])))
                                 []
                                 infos))))
                         new-cols))]
        (recur (next line-map-seq) (assoc new-lines line new-cols)))
      new-lines)))
(defn encode*
  "Take an internal source map representation represented as nested\n   sorted maps of file, line, column and return a v3 representation."
  [m opts]
  (let [lines (atom [[]])
        names->idx (atom {})
        name-idx (atom 0)
        preamble-lines (take
                         (or (:preamble-line-count opts) 0)
                         (repeat []))
        info->segv (fn [info source-idx line col]
                     (let [segv [(:gcol info) source-idx line col]]
                       (if-let [name (:name info)]
                         (let [idx (if-let 
                                     [idx
                                      (get
                                        (clojure.core/deref names->idx)
                                        name)]
                                     idx
                                     (let 
                                       [cidx
                                        (clojure.core/deref name-idx)]
                                       (swap!
                                         names->idx
                                         assoc
                                         name
                                         cidx)
                                       (swap! name-idx inc)
                                       cidx))]
                           (conj segv idx))
                         segv)))
        encode-cols (fn [infos source-idx line col]
                      (doseq [info infos]
                        (let [segv (info->segv
                                     info
                                     source-idx
                                     line
                                     col)
                              gline (:gline info)
                              lc (count (clojure.core/deref lines))]
                          (if (> gline (dec lc))
                            (swap!
                              lines
                              (fn [lines]
                                (conj
                                  (into
                                    lines
                                    (repeat
                                      (dec (- gline (dec lc)))
                                      []))
                                  [segv])))
                            (swap!
                              lines
                              (fn [lines]
                                (update-in
                                  lines
                                  [gline]
                                  conj
                                  segv)))))))]
    (doseq [[source-idx [_ lines]] (map-indexed (fn [i v] [i v]) m)]
      (doseq [[line cols] lines]
        (doseq [[col infos] cols]
          (encode-cols infos source-idx line col))))
    (cond->
      {"version" 3 
       "file" (:file opts) 
       "sources"
       (into
         []
         (let [paths (keys m)
               f (comp
                   (if (true? (:source-map-timestamp opts))
                     (fn [uri]
                       (if-not (string/index-of uri "?")
                         (str uri "?rel=" (System/currentTimeMillis))
                         (str uri "&rel=" (System/currentTimeMillis))))
                     identity)
                   (if (or (:output-dir opts) (:source-map-path opts))
                     (fn* [p1__4880#] (relativize-path p1__4880# opts))
                     (fn*
                       [p1__4881#]
                       (last (string/split p1__4881# #"/")))))]
           (map f paths))) 
       "lineCount" (:lines opts) 
       "mappings"
       (->>
         (lines->segs
           (concat preamble-lines (clojure.core/deref lines)))
         (map (fn* [p1__4882#] (string/join "," p1__4882#)))
         (string/join ";")) 
       "names"
       (into
         []
         (map
           (set/map-invert (clojure.core/deref names->idx))
           (range (count (clojure.core/deref names->idx)))))}
      (:sources-content opts)
      (assoc "sourcesContent" (:sources-content opts)))))
(defn encode
  "Take an internal source map representation represented as nested\n   sorted maps of file, line, column and return a source map v3 JSON\n   string."
  [m opts]
  (let [source-map-file-contents (encode* m opts)]
    (if (true? (:source-map-pretty-print opts))
      (with-out-str
        (json/pprint source-map-file-contents :escape-slash false))
      (json/write-str source-map-file-contents))))
(defn relativize-path
  "Relativize a path using :source-map-path if provided or the parent directory\n   otherwise."
  [path
   {:keys [output-dir source-map-path source-map relpaths]  :as opts}]
  (let [bare-munged-path (cond
                           (re-find #"\.jar!/" path) (str
                                                       (or
                                                         source-map-path
                                                         output-dir)
                                                       (second
                                                         (string/split
                                                           path
                                                           #"\.jar!")))
                           :else (str
                                   (or source-map-path output-dir)
                                   "/"
                                   (get relpaths path)))]
    (cond
      source-map-path bare-munged-path
      :else (let [unrel-uri (-> bare-munged-path io/file .toURI)
                  sm-parent-uri (->
                                 source-map
                                 io/file
                                 .getAbsoluteFile
                                 .getParentFile
                                 .toURI)]
              (str (.relativize sm-parent-uri unrel-uri))))))
(defn decode
  "Convert a v3 source map JSON object into a nested sorted map\n   organized as file, line, and column. Note this source map\n   maps from *generated* source location to original source\n   location."
  ([source-map] (decode (:mappings source-map) source-map))
  ([mappings source-map]
    (let [relseg-init [0 0 0 0 0]
          lines (seq (string/split mappings #";"))]
      (loop [gline 0 lines lines relseg relseg-init result {}]
        (if lines
          (let [line (first lines)
                [result relseg] (if
                                  (string/blank? line)
                                  [result relseg]
                                  (let 
                                    [segs
                                     (seq (string/split line #","))]
                                    (loop 
                                      [segs segs
                                       relseg relseg
                                       result result]
                                      (if
                                        segs
                                        (let 
                                          [seg (first segs)
                                           nrelseg
                                           (seg-combine
                                             (base64-vlq/decode seg)
                                             relseg)]
                                          (recur
                                            (next segs)
                                            nrelseg
                                            (update-result
                                              result
                                              (seg->map
                                                nrelseg
                                                source-map)
                                              gline)))
                                        [result relseg]))))]
            (recur (inc gline) (next lines) (assoc relseg 0 0) result))
          result)))))
(defn update-result
  "Helper for decode. Take a source map and update it based on a\n  segment map."
  [result segmap gline]
  (let [{:keys [gcol source line col name]} segmap
        d {:line line  :col col  :source source}
        d (if name (assoc d :name name) d)]
    (update-in
      result
      [gline]
      (fnil
        (fn [m]
          (update-in
            m
            [gcol]
            (fnil (fn* [p1__4840#] (conj p1__4840# d)) [])))
        (sorted-map)))))
(defn invert-reverse-map
  "Given a ClojureScript to JavaScript source map, invert it. Useful when\n   mapping JavaScript stack traces when environment support is unavailable."
  [reverse-map]
  (let [inverted (atom (sorted-map))]
    (doseq [[line columns] reverse-map]
      (doseq [[column column-info] columns]
        (doseq [{:keys [gline gcol name]} column-info]
          (swap!
            inverted
            update-in
            [gline]
            (fnil
              (fn [columns]
                (update-in
                  columns
                  [column]
                  (fnil conj [])
                  {:line line  :col column  :name name}))
              (sorted-map))))))
    (clojure.core/deref inverted)))
cljs.test-util 186/187 (99.5%)
(defmethod
  clojure.test/assert-expr
  (quote thrown-with-cause-msg?)
  [msg form]
  (let [klass (nth form 1) re (nth form 2) body (nthnext form 3)]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote try))
        body
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.test/do-report))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/hash-map
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list :type)
                      (clojure.core/list :fail)
                      (clojure.core/list :message)
                      (clojure.core/list msg)
                      (clojure.core/list :expected)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote quote))
                            (clojure.core/list form))))
                      (clojure.core/list :actual)
                      (clojure.core/list (quote nil)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote catch))
              (clojure.core/list klass)
              (clojure.core/list (quote e__6123__auto__))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote m__6124__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote if))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote .getCause))
                                        (clojure.core/list
                                          (quote e__6123__auto__)))))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list (quote ..))
                                        (clojure.core/list
                                          (quote e__6123__auto__))
                                        (clojure.core/list
                                          (quote
                                            cljs.test-util/getCause))
                                        (clojure.core/list
                                          (quote
                                            cljs.test-util/getMessage)))))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote .getMessage))
                                        (clojure.core/list
                                          (quote
                                            e__6123__auto__))))))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote if))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/re-find))
                                (clojure.core/list re)
                                (clojure.core/list
                                  (quote m__6124__auto__)))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.test/do-report))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list :type)
                                        (clojure.core/list :pass)
                                        (clojure.core/list :message)
                                        (clojure.core/list msg)
                                        (clojure.core/list :expected)
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote quote))
                                              (clojure.core/list
                                                form))))
                                        (clojure.core/list :actual)
                                        (clojure.core/list
                                          (quote
                                            e__6123__auto__)))))))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.test/do-report))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list :type)
                                        (clojure.core/list :fail)
                                        (clojure.core/list :message)
                                        (clojure.core/list msg)
                                        (clojure.core/list :expected)
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote quote))
                                              (clojure.core/list
                                                form))))
                                        (clojure.core/list :actual)
                                        (clojure.core/list
                                          (quote
                                            e__6123__auto__)))))))))))))))
              (clojure.core/list (quote e__6123__auto__)))))))))
(defn unsplit-lines
  "Forms a string wherein each line is followed by a system-dependent newline.\n  Roughly an inverse of clojure.string/split-lines."
  [lines]
  (with-out-str (run! println lines)))
(defn delete-out-files
  "Processed files are only copied/written if input has changed. In test case it\n   makes sense to write files always, in case the processing logic has changed."
  ([] (delete-out-files "out"))
  ([directory]
    (doseq [f (file-seq (io/file directory)) :when (.isFile f)]
      (.delete f))))
(defn tmp-dir
  "Returns the temporary directory of the system."
  []
  (System/getProperty "java.io.tmpdir"))
(defn equiv-modulo-newlines
  "Returns whether strings are equivalent, disregarding differences in\n  embedded system-dependent newlines."
  [s & more]
  (== 1 (count (group-by string/split-lines (list* s more)))))
(defn project-with-modules
  "Returns the build config for a project that uses Google Closure modules."
  [output-dir]
  {:inputs (str (io/file "src" "test" "cljs")) 
   :opts
   {:main "module-test.main" 
    :output-dir output-dir 
    :optimizations :advanced 
    :verbose true 
    :language-in :es6 
    :modules
    {:cljs-base
     {:output-to (str (io/file output-dir "module-main.js"))} 
     :module-a
     {:output-to (str (io/file output-dir "module-a.js")) 
      :entries #{(quote module-test.modules.a)}} 
     :module-b
     {:output-to (str (io/file output-dir "module-b.js")) 
      :entries #{(quote module-test.modules.b)}}} 
    :closure-warnings {:check-types :off}}})
(defn platform-path [path]
  (.replace path \/ (.charAt (str File/separator) 0)))
(defn document-write?
  "Returns true if the string `s` contains a document.write statement to\n  load the namespace `ns`, otherwise false."
  [s ns]
  (->>
    (format
      "document.write('');"
      ns)
    (string/index-of s)
    (some?)))
(defn delete-node-modules []
  (let [nm (io/file "node_modules")]
    (while (.exists nm) (doseq [f (file-seq nm)] (.delete f)))))
cljs.analyzer.passes.and-or 165/165 (100.0%)
(defn ->expr-env [ast] (assoc-in ast [:env :context] :expr))
(defn simple-test-binding-let? [ast]
  (and
    (single-binding-let? ast)
    (no-statements? ast)
    (simple-test-expr? (-> ast :bindings first :init))
    (returns-if? ast)))
(defn simple-or? [ast]
  (and (simple-test-binding-let? ast) (test=then? (-> ast :body :ret))))
(defn simple-op? [ast] (contains? simple-ops (:op ast)))
(defn simple-and? [ast]
  (and (simple-test-binding-let? ast) (test=else? (-> ast :body :ret))))
(defn remove-local-pass [local]
  (fn [env ast opts]
    (cond->
      (update-in ast [:env :locals] dissoc local)
      (= :fn (:op ast))
      (remove-loop-let local))))
(defn simple-test-expr? [{:keys [op]  :as ast}]
  (boolean
    (and
      (simple-op? ast)
      ((quote #{seq boolean})
        (or
          (:tag ast)
          (when (#{:var :local} op) (-> ast :info :tag)))))))
(defn optimizable-and? [ast]
  (and (simple-and? ast) (simple-test-expr? (-> ast :body :ret :then))))
(defn optimizable-or? [ast]
  (and (simple-or? ast) (simple-test-expr? (-> ast :body :ret :else))))
(defn optimize-and [ast]
  (let [{:keys [init name]} (-> ast :bindings first)]
    {:op :js 
     :env (:env ast) 
     :segs ["((" ") && (" "))"] 
     :args
     [init
      (passes/walk
        (->expr-env (-> ast :body :ret :then))
        [(remove-local-pass name)])] 
     :form (:form ast) 
     :children [:args] 
     :tag (quote boolean)}))
(defn optimize-or [ast]
  (let [{:keys [init name]} (-> ast :bindings first)]
    {:op :js 
     :env (:env ast) 
     :segs ["((" ") || (" "))"] 
     :args
     [init
      (passes/walk
        (->expr-env (-> ast :body :ret :else))
        [(remove-local-pass name)])] 
     :form (:form ast) 
     :children [:args] 
     :tag (quote boolean)}))
(defn single-binding-let? [ast]
  (and (= :let (:op ast)) (= 1 (count (-> ast :bindings)))))
(defn no-statements? [let-ast] (= [] (-> let-ast :body :statements)))
(defn test=else? [if-ast]
  (= (dissoc (:test if-ast) :env) (dissoc (:else if-ast) :env)))
(defn returns-if? [let-ast] (= :if (-> let-ast :body :ret :op)))
(defn remove-loop-let [fn-ast local]
  (update
    fn-ast
    :loop-lets
    (fn [loop-lets]
      (map
        (fn [m]
          (update
            m
            :params
            (fn [xs]
              (remove
                (fn* [p1__645#] (= local (:name p1__645#)))
                xs))))
        loop-lets))))
(defn optimize [env ast _]
  (cond
    (optimizable-and? ast) (optimize-and ast)
    (optimizable-or? ast) (optimize-or ast)
    :else ast))
(defn test=then? [if-ast]
  (= (dissoc (:test if-ast) :env) (dissoc (:then if-ast) :env)))
cljs.env 160/160 (100.0%)
(defn default-compiler-env* [options]
  (merge
    {:cljs.analyzer/namespaces
     {(quote cljs.user) {:name (quote cljs.user)}} 
     :cljs.analyzer/constant-table {} 
     :cljs.analyzer/data-readers {} 
     :cljs.analyzer/externs
     (externs/externs-map (:externs-sources options)) 
     :options options}
    (when (and
            (= :nodejs (:target options))
            (not (false? (:nodejs-rt options))))
      {:node-module-index deps/native-node-modules})
    {:js-dependency-index (deps/js-dependency-index options)}))
(clojure.core/defn ensure
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote val__1533__auto__))
                (clojure.core/list (quote cljs.env/*compiler*))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote if))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/nil?))
                    (clojure.core/list (quote val__1533__auto__)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list
                      (quote clojure.core/push-thread-bindings))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/hash-map))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote var))
                                (clojure.core/list
                                  (quote cljs.env/*compiler*)))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote
                                    cljs.env/default-compiler-env))))))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote try))
              body
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote finally))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote if))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/nil?))
                                (clojure.core/list
                                  (quote val__1533__auto__)))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote
                                    clojure.core/pop-thread-bindings))))))))))))))))))
(defn default-compiler-env
  ([] (default-compiler-env {}))
  ([options] (atom (default-compiler-env* options))))
(clojure.core/defn with-compiler-env
  "Evaluates [body] with [env] bound as the value of the `*compiler*` var in\n   this namespace."
  ([&form &env env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote env__1527__auto__))
                (clojure.core/list env)
                (clojure.core/list (quote env__1527__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote clojure.core/cond))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/map?))
                            (clojure.core/list
                              (quote env__1527__auto__)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/atom))
                            (clojure.core/list
                              (quote env__1527__auto__)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/and))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/instance?))
                                  (clojure.core/list
                                    (quote clojure.lang.Atom))
                                  (clojure.core/list
                                    (quote env__1527__auto__)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/map?))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote clojure.core/deref))
                                        (clojure.core/list
                                          (quote
                                            env__1527__auto__)))))))))))
                      (clojure.core/list (quote env__1527__auto__))
                      (clojure.core/list :default)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote throw))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote
                                      java.lang.IllegalArgumentException.))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote clojure.core/str))
                                        (clojure.core/list
                                          "Compiler environment must be a map or atom containing a map, not ")
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote
                                                  clojure.core/class))
                                              (clojure.core/list
                                                (quote
                                                  env__1527__auto__)))))))))))))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.env/*compiler*))
                      (clojure.core/list (quote env__1527__auto__))))))
              body)))))))
cljs.analyzer.passes 49/49 (100.0%)
(defn walk
  ([ast passes] (walk ast passes nil))
  ([ast passes opts]
    (reduce
      (fn [ast child-k]
        (assoc
          ast
          child-k
          (let [child (get ast child-k)]
            (if (vector? child)
              (into
                []
                (map (fn* [p1__609#] (walk p1__609# passes opts)))
                child)
              (walk child passes opts)))))
      (some-> ast (apply-passes passes opts))
      (:children ast))))
(defn apply-passes
  ([ast passes] (apply-passes ast passes nil))
  ([ast passes opts]
    (reduce (fn [ast pass] (pass (:env ast) ast opts)) ast passes)))
cljs.core 6716/8652 (77.6%)
(clojure.core/defn hash-map
  ([&form &env]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote .-EMPTY))
        (clojure.core/list (quote cljs.core/PersistentHashMap)))))
  ([&form &env & kvs]
    (core/let
      [pairs
       (map
         (core/fn [pair] (remove #{:cljs.core/missing} pair))
         (partition 2 2 (repeat :cljs.core/missing) kvs))
       ks
       (map first pairs)
       vs
       (map
         second
         (take-while (fn* [p1__7552#] (= 2 (count p1__7552#))) pairs))]
      (vary-meta
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote .fromArrays))
            (clojure.core/list (quote cljs.core/PersistentHashMap))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  ks)))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  vs)))))
        assoc
        :tag
        (quote cljs.core/PersistentHashMap)))))
(clojure.core/defn bit-test
  ([&form &env x n]
    (bool-expr
      (core/list (quote js*) "((~{} & (1 << ~{})) != 0)" x n))))
(clojure.core/defn dec
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        (clojure.core/list x)
        (clojure.core/list 1)))))
(clojure.core/defn bit-clear
  ([&form &env x n] (core/list (quote js*) "(~{} & ~(1 << ~{}))" x n)))
(core/defn-
  ->impl-map
  [impls]
  (core/loop
    [ret {} s impls]
    (if (seq s)
      (recur
        (assoc ret (first s) (take-while seq? (next s)))
        (drop-while seq? (next s)))
      ret)))
(core/defn-
  base-assign-impls
  [env resolve tsym type [p sigs]]
  (update-protocol-var p tsym env)
  (core/let
    [psym
     (resolve p)
     pfn-prefix
     (subs
       (core/str psym)
       0
       (clojure.core/inc (.indexOf (core/str psym) "/")))]
    (cons
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/unchecked-set))
          (clojure.core/list psym)
          (clojure.core/list type)
          (clojure.core/list (quote true))))
      (map
        (core/fn
          [[f & meths :as form]]
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/unchecked-set))
              (clojure.core/list (symbol (core/str pfn-prefix f)))
              (clojure.core/list type)
              (clojure.core/list
                (with-meta
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      meths))
                  (meta form))))))
        sigs))))
(clojure.core/defn deftype
  "(deftype name [fields*]  options* specs*)\n\n  Currently there are no options.\n\n  Each spec consists of a protocol or interface name followed by zero\n  or more method bodies:\n\n  protocol-or-Object\n  (methodName [args*] body)*\n\n  The type will have the (by default, immutable) fields named by\n  fields, which can have type hints. Protocols and methods\n  are optional. The only methods that can be supplied are those\n  declared in the protocols/interfaces.  Note that method bodies are\n  not closures, the local environment includes only the named fields,\n  and those fields can be accessed directly. Fields can be qualified\n  with the metadata :mutable true at which point (set! afield aval) will be\n  supported in method bodies. Note well that mutable fields are extremely\n  difficult to use correctly, and are present only to facilitate the building\n  of higherlevel constructs, such as ClojureScript's reference types, in\n  ClojureScript itself. They are for experts only - if the semantics and\n  implications of :mutable are not immediately apparent to you, you should not\n  be using them.\n\n  Method definitions take the form:\n\n  (methodname [args*] body)\n\n  The argument and return types can be hinted on the arg and\n  methodname symbols. If not supplied, they will be inferred, so type\n  hints should be reserved for disambiguation.\n\n  Methods should be supplied for all methods of the desired\n  protocol(s). You can also define overrides for methods of Object. Note that\n  a parameter must be supplied to correspond to the target object\n  ('this' in JavaScript parlance). Note also that recur calls to the method\n  head should *not* pass the target object, it will be supplied\n  automatically and can not be substituted.\n\n  In the method bodies, the (unqualified) name can be used to name the\n  class (for calls to new, instance? etc).\n\n  One constructor will be defined, taking the designated fields.  Note\n  that the field names __meta and __extmap are currently reserved and\n  should not be used when defining your own types.\n\n  Given (deftype TypeName ...), a factory function called ->TypeName\n  will be defined, taking positional parameters for the fields"
  ([&form &env t fields & impls]
    (validate-fields "deftype" t fields)
    (core/let
      [env
       &env
       r
       (:name (cljs.analyzer/resolve-var (dissoc env :locals) t))
       [fpps pmasks]
       (prepare-protocol-masks env impls)
       protocols
       (collect-protocols impls env)
       t
       (vary-meta
         t
         assoc
         :protocols
         protocols
         :skip-protocol-flag
         fpps)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote deftype*))
                (clojure.core/list t)
                (clojure.core/list fields)
                (clojure.core/list pmasks)
                (clojure.core/list
                  (if (seq impls)
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list
                          (quote cljs.core/extend-type))
                        (clojure.core/list t)
                        (dt->et t impls fields))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-getBasis))
                      (clojure.core/list t))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq (clojure.core/concat))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote quote))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    fields)))))))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-cljs$lang$type))
                      (clojure.core/list t))))
                (clojure.core/list (quote true)))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-cljs$lang$ctorStr))
                      (clojure.core/list t))))
                (clojure.core/list (core/str r)))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote .-cljs$lang$ctorPrWriter))
                      (clojure.core/list t))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote this__7213__auto__))
                              (clojure.core/list
                                (quote writer__7214__auto__))
                              (clojure.core/list
                                (quote opt__7215__auto__))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/-write))
                            (clojure.core/list
                              (quote writer__7214__auto__))
                            (clojure.core/list (core/str r)))))))))))
          (clojure.core/list (build-positional-factory t r fields))
          (clojure.core/list t))))))
(core/defn-
  variadic-fn*
  ([sym method] (variadic-fn* sym method true))
  ([sym [arglist & body :as method] solo]
    (core/let
      [sig (remove (quote #{&}) arglist) restarg (gensym "seq")]
      (core/letfn
        [(get-delegate [] (quote cljs$core$IFn$_invoke$arity$variadic))
         (get-delegate-prop [] (symbol (core/str "-" (get-delegate))))
         (param-bind
           [param]
           (clojure.core/apply
             clojure.core/vector
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list param)
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list
                         (clojure.core/with-meta
                           (quote clojure.core/first)
                           (clojure.core/apply
                             clojure.core/hash-map
                             (clojure.core/seq
                               (clojure.core/concat
                                 (clojure.core/list
                                   :cljs.analyzer/no-resolve)
                                 (clojure.core/list (quote true)))))))
                       (clojure.core/list restarg))))
                 (clojure.core/list restarg)
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list
                         (clojure.core/with-meta
                           (quote clojure.core/next)
                           (clojure.core/apply
                             clojure.core/hash-map
                             (clojure.core/seq
                               (clojure.core/concat
                                 (clojure.core/list
                                   :cljs.analyzer/no-resolve)
                                 (clojure.core/list (quote true)))))))
                       (clojure.core/list restarg))))))))
         (apply-to
           []
           (if (core/< 1 (count sig))
             (core/let
               [params (repeatedly (core/dec (count sig)) gensym)]
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote cljs.core/fn))
                   (clojure.core/list
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list
                           (clojure.core/apply
                             clojure.core/vector
                             (clojure.core/seq
                               (clojure.core/concat
                                 (clojure.core/list restarg)))))
                         (clojure.core/list
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list
                                 (quote cljs.core/let))
                               (clojure.core/list
                                 (clojure.core/apply
                                   clojure.core/vector
                                   (clojure.core/seq
                                     (clojure.core/concat
                                       (mapcat param-bind params)))))
                               (clojure.core/list
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list
                                       (quote cljs.core/this-as))
                                     (clojure.core/list
                                       (quote self__7849__auto__))
                                     (clojure.core/list
                                       (clojure.core/seq
                                         (clojure.core/concat
                                           (clojure.core/list
                                             (quote .))
                                           (clojure.core/list
                                             (quote
                                               self__7849__auto__))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (get-delegate))
                                                 params
                                                 (clojure.core/list
                                                   restarg)))))))))))))))))))
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote cljs.core/fn))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list
                         (clojure.core/apply
                           clojure.core/vector
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list restarg)))))
                       (clojure.core/list
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list
                               (quote cljs.core/this-as))
                             (clojure.core/list
                               (quote self__7850__auto__))
                             (clojure.core/list
                               (clojure.core/seq
                                 (clojure.core/concat
                                   (clojure.core/list (quote .))
                                   (clojure.core/list
                                     (quote self__7850__auto__))
                                   (clojure.core/list
                                     (clojure.core/seq
                                       (clojure.core/concat
                                         (clojure.core/list
                                           (get-delegate))
                                         (clojure.core/list
                                           (clojure.core/seq
                                             (clojure.core/concat
                                               (clojure.core/list
                                                 (quote
                                                   clojure.core/seq))
                                               (clojure.core/list
                                                 restarg))))))))))))))))))))]
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote do))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote set!))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote .))
                        (clojure.core/list sym)
                        (clojure.core/list (get-delegate-prop)))))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/fn))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (vec sig))
                              body)))))))))
            (core/when
              solo
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote set!))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote .))
                                (clojure.core/list sym)
                                (clojure.core/list
                                  (quote -cljs$lang$maxFixedArity)))))
                          (clojure.core/list
                            (core/dec (count sig))))))))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote cljs.core/js-inline-comment))
                  (clojure.core/list " @this {Function} "))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote set!))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote .))
                        (clojure.core/list
                          (vary-meta sym dissoc :top-fn))
                        (clojure.core/list
                          (quote -cljs$lang$applyTo)))))
                  (clojure.core/list (apply-to)))))))))))
(clojure.core/defn defrecord
  "(defrecord name [fields*]  options* specs*)\n\n  Currently there are no options.\n\n  Each spec consists of a protocol or interface name followed by zero\n  or more method bodies:\n\n  protocol-or-Object\n  (methodName [args*] body)*\n\n  The record will have the (immutable) fields named by\n  fields, which can have type hints. Protocols and methods\n  are optional. The only methods that can be supplied are those\n  declared in the protocols.  Note that method bodies are\n  not closures, the local environment includes only the named fields,\n  and those fields can be accessed directly.\n\n  Method definitions take the form:\n\n  (methodname [args*] body)\n\n  The argument and return types can be hinted on the arg and\n  methodname symbols. If not supplied, they will be inferred, so type\n  hints should be reserved for disambiguation.\n\n  Methods should be supplied for all methods of the desired\n  protocol(s). You can also define overrides for\n  methods of Object. Note that a parameter must be supplied to\n  correspond to the target object ('this' in JavaScript parlance). Note also\n  that recur calls to the method head should *not* pass the target object, it\n  will be supplied automatically and can not be substituted.\n\n  In the method bodies, the (unqualified) name can be used to name the\n  class (for calls to new, instance? etc).\n\n  The type will have implementations of several ClojureScript\n  protocol generated automatically: IMeta/IWithMeta (metadata support) and\n  IMap, etc.\n\n  In addition, defrecord will define type-and-value-based =,\n  and will define ClojureScript IHash and IEquiv.\n\n  Two constructors will be defined, one taking the designated fields\n  followed by a metadata map (nil for none) and an extension field\n  map (nil for none), and one taking only the fields (using nil for\n  meta and extension fields). Note that the field names __meta\n  and __extmap are currently reserved and should not be used when\n  defining your own records.\n\n  Given (defrecord TypeName ...), two factory functions will be\n  defined: ->TypeName, taking positional parameters for the fields,\n  and map->TypeName, taking a map of keywords to field values."
  ([&form &env rsym fields & impls]
    (validate-fields "defrecord" rsym fields)
    (core/let
      [rsym
       (vary-meta rsym assoc :internal-ctor true)
       r
       (vary-meta
         (:name (cljs.analyzer/resolve-var (dissoc &env :locals) rsym))
         assoc
         :internal-ctor
         true)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq (clojure.core/concat))))
          (clojure.core/list (emit-defrecord &env rsym r fields impls))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-getBasis))
                      (clojure.core/list r))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq (clojure.core/concat))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote quote))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    fields)))))))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-cljs$lang$type))
                      (clojure.core/list r))))
                (clojure.core/list (quote true)))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .-cljs$lang$ctorPrSeq))
                      (clojure.core/list r))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote this__7276__auto__))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/list))
                            (clojure.core/list (core/str r)))))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote .-cljs$lang$ctorPrWriter))
                      (clojure.core/list r))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote this__7276__auto__))
                              (clojure.core/list
                                (quote writer__7277__auto__))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/-write))
                            (clojure.core/list
                              (quote writer__7277__auto__))
                            (clojure.core/list (core/str r)))))))))))
          (clojure.core/list (build-positional-factory rsym r fields))
          (clojure.core/list (build-map-factory rsym r fields))
          (clojure.core/list r))))))
(core/defn-
  assoc-test
  [m test expr env]
  (if (contains? m test)
    (throw
      (clojure.core/IllegalArgumentException.
        (core/str
          "Duplicate case test constant '"
          test
          "'"
          (core/when
            (:line env)
            (core/str
              " on line "
              (:line env)
              " "
              cljs.analyzer/*cljs-file*)))))
    (assoc m test expr)))
(clojure.core/defn true?
  ([&form &env x] (bool-expr (core/list (quote js*) "~{} === true" x))))
(clojure.core/defn zero?
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/==))
        (clojure.core/list x)
        (clojure.core/list 0)))))
(clojure.core/defn identical?
  ([&form &env a b]
    (bool-expr (core/list (quote js*) "(~{} === ~{})" a b))))
(clojure.core/defn binding
  "binding => var-symbol init-expr\n\n  Creates new bindings for the (already-existing) vars, with the\n  supplied initial values, executes the exprs in an implicit do, then\n  re-establishes the bindings that existed before.  The new bindings\n  are made in parallel (unlike let); all init-exprs are evaluated\n  before the vars are bound to their new values."
  ([&form &env bindings & body]
    (core/let
      [names (take-nth 2 bindings)]
      (cljs.analyzer/confirm-bindings &env names)
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/with-redefs))
          (clojure.core/list bindings)
          body)))))
(core/defn-
  add-ifn-methods
  [type type-sym [f & meths :as form]]
  (core/let
    [meths
     (map (fn* [p1__7138#] (adapt-ifn-params type p1__7138#)) meths)
     this-sym
     (with-meta (quote self__) {:tag type})
     argsym
     (gensym "args")
     max-ifn-arity
     20]
    (concat
      [(clojure.core/seq
         (clojure.core/concat
           (clojure.core/list (quote set!))
           (clojure.core/list (extend-prefix type-sym (quote call)))
           (clojure.core/list
             (with-meta
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote cljs.core/fn))
                   meths))
               (meta form)))))
       (clojure.core/seq
         (clojure.core/concat
           (clojure.core/list (quote set!))
           (clojure.core/list (extend-prefix type-sym (quote apply)))
           (clojure.core/list
             (with-meta
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote cljs.core/fn))
                   (clojure.core/list [this-sym argsym])
                   (clojure.core/list
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list (quote cljs.core/this-as))
                         (clojure.core/list this-sym)
                         (clojure.core/list
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list
                                 (quote cljs.core/let))
                               (clojure.core/list
                                 (clojure.core/apply
                                   clojure.core/vector
                                   (clojure.core/seq
                                     (clojure.core/concat
                                       (clojure.core/list
                                         (quote args__7139__auto__))
                                       (clojure.core/list
                                         (clojure.core/seq
                                           (clojure.core/concat
                                             (clojure.core/list
                                               (quote
                                                 cljs.core/aclone))
                                             (clojure.core/list
                                               argsym))))))))
                               (clojure.core/list
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list (quote .apply))
                                     (clojure.core/list
                                       (clojure.core/seq
                                         (clojure.core/concat
                                           (clojure.core/list
                                             (quote .-call))
                                           (clojure.core/list
                                             this-sym))))
                                     (clojure.core/list this-sym)
                                     (clojure.core/list
                                       (clojure.core/seq
                                         (clojure.core/concat
                                           (clojure.core/list
                                             (quote .concat))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote
                                                     cljs.core/array))
                                                 (clojure.core/list
                                                   this-sym))))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote if))
                                                 (clojure.core/list
                                                   (clojure.core/seq
                                                     (clojure.core/concat
                                                       (clojure.core/list
                                                         (quote
                                                           cljs.core/>))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 .-length))
                                                             (clojure.core/list
                                                               (quote
                                                                 args__7139__auto__)))))
                                                       (clojure.core/list
                                                         max-ifn-arity))))
                                                 (clojure.core/list
                                                   (clojure.core/seq
                                                     (clojure.core/concat
                                                       (clojure.core/list
                                                         (quote
                                                           cljs.core/doto))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 .slice))
                                                             (clojure.core/list
                                                               (quote
                                                                 args__7139__auto__))
                                                             (clojure.core/list
                                                               0)
                                                             (clojure.core/list
                                                               max-ifn-arity))))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 .push))
                                                             (clojure.core/list
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     (quote
                                                                       .slice))
                                                                   (clojure.core/list
                                                                     (quote
                                                                       args__7139__auto__))
                                                                   (clojure.core/list
                                                                     max-ifn-arity))))))))))
                                                 (clojure.core/list
                                                   (quote
                                                     args__7139__auto__)))))))))))))))))))
               (meta form)))))]
      (ifn-invoke-methods type type-sym form))))
(clojure.core/defn with-redefs
  "binding => var-symbol temp-value-expr\n\n  Temporarily redefines vars while executing the body.  The\n  temp-value-exprs will be evaluated and each resulting value will\n  replace in parallel the root value of its var.  After the body is\n  executed, the root values of all the vars will be set back to their\n  old values. Useful for mocking out functions during testing."
  ([&form &env bindings & body]
    (core/let
      [names
       (take-nth 2 bindings)
       vals
       (take-nth 2 (drop 1 bindings))
       orig-val-syms
       (map
         (comp
           gensym
           (fn* [p1__7374#] (core/str p1__7374# "-orig-val__"))
           name)
         names)
       temp-val-syms
       (map
         (comp
           gensym
           (fn* [p1__7375#] (core/str p1__7375# "-temp-val__"))
           name)
         names)
       binds
       (map core/vector names temp-val-syms)
       resets
       (reverse (map core/vector names orig-val-syms))
       bind-value
       (core/fn [[k v]] (core/list (quote set!) k v))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (interleave orig-val-syms names)
                  (interleave temp-val-syms vals)))))
          (map bind-value binds)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote try))
                body
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote finally))
                      (map bind-value resets))))))))))))
(clojure.core/defn import-macros
  ([&form &env ns [& vars]]
    (core/let
      [ns
       (find-ns ns)
       vars
       (map (fn* [p1__6329#] (ns-resolve ns p1__6329#)) vars)
       syms
       (map
         (core/fn
           [v]
           (core/->
             v
             .sym
             (with-meta
               (merge
                 {:macro true}
                 (update-in
                   (select-keys (meta v) [:arglists :doc :file :line])
                   [:arglists]
                   (core/fn
                     [arglists]
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list (quote quote))
                         (clojure.core/list arglists)))))))))
         vars)
       defs
       (map
         (core/fn
           [sym var]
           (core/let
             [{:keys [arglists doc file line]} (meta sym)]
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote do))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list (quote def))
                       (clojure.core/list sym)
                       (clojure.core/list
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list
                               (quote clojure.core/deref))
                             (clojure.core/list var)))))))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list
                         (quote clojure.core/alter-meta!))
                       (clojure.core/list
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list (quote var))
                             (clojure.core/list sym))))
                       (clojure.core/list (quote clojure.core/assoc))
                       (clojure.core/list :macro)
                       (clojure.core/list (quote true))
                       (clojure.core/list :arglists)
                       (clojure.core/list arglists)
                       (clojure.core/list :doc)
                       (clojure.core/list doc)
                       (clojure.core/list :file)
                       (clojure.core/list file)
                       (clojure.core/list :line)
                       (clojure.core/list line))))))))
         syms
         vars)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          defs
          (clojure.core/list :imported))))))
(clojure.core/defn dotimes
  "bindings => name n\n\n  Repeatedly executes body (presumably for side-effects) with name\n  bound to integers from 0 through n-1."
  ([&form &env bindings & body]
    (core/let
      [i (first bindings) n (second bindings)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote n__7623__auto__))
                  (clojure.core/list n)))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/loop))
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list i)
                        (clojure.core/list 0)))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/when))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/<))
                            (clojure.core/list i)
                            (clojure.core/list
                              (quote n__7623__auto__)))))
                      body
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote recur))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/inc))
                                  (clojure.core/list i))))))))))))))))))
(clojure.core/defn unchecked-get
  "INTERNAL. Compiles to JavaScript property access using bracket notation. Does\n  not distinguish between object and array types and not subject to compiler\n  static analysis."
  ([&form &env obj key] (core/list (quote js*) "(~{}[~{}])" obj key)))
(clojure.core/defn vswap!
  "Non-atomically swaps the value of the volatile as if:\n   (apply f current-value-of-vol args). Returns the value that\n   was swapped in."
  ([&form &env vol f & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-vreset!))
        (clojure.core/list vol)
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list f)
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/-deref))
                    (clojure.core/list vol))))
              args)))))))
(clojure.core/defn bitpos
  ([&form &env hash shift]
    (core/list
      (quote js*)
      "(1 << ~{})"
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/mask))
          (clojure.core/list hash)
          (clojure.core/list shift))))))
(clojure.core/defn bit-not
  ([&form &env x] (core/list (quote js*) "(~ ~{})" x)))
(clojure.core/defn js-mod
  ([&form &env num div] (core/list (quote js*) "(~{} % ~{})" num div)))
(clojure.core/defn and
  "Evaluates exprs one at a time, from left to right. If a form\n  returns logical false (nil or false), and returns that value and\n  doesn't evaluate any of the other expressions, otherwise it returns\n  the value of the last expr. (and) returns true."
  ([&form &env] true)
  ([&form &env x] x)
  ([&form &env x & next]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote and__6530__auto__))
                (clojure.core/list x)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote if))
              (clojure.core/list (quote and__6530__auto__))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/and))
                    next)))
              (clojure.core/list (quote and__6530__auto__)))))))))
(core/defn-
  type-hint-first-arg
  [type-sym argv]
  (assoc argv 0 (vary-meta (argv 0) assoc :tag type-sym)))
(core/defn-
  protocol-prefix
  [psym]
  (core/str
    (core/-> (core/str psym) (.replace \. \$) (.replace \/ \$))
    "$"))
(clojure.core/defn coercive-boolean
  ([&form &env x]
    (with-meta (core/list (quote js*) "~{}" x) {:tag (quote boolean)})))
(clojure.core/defn alength
  ([&form &env a]
    (vary-meta
      (core/list (quote js*) "~{}.length" a)
      assoc
      :tag
      (quote number))))
(clojure.core/defn symbol?
  ([&form &env x]
    (bool-expr
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/instance?))
          (clojure.core/list (quote cljs.core/Symbol))
          (clojure.core/list x))))))
(clojure.core/defn require
  "Loads libs, skipping any that are already loaded. Each argument is\n  either a libspec that identifies a lib or a flag that modifies how all the identified\n  libs are loaded. Use :require in the ns macro in preference to calling this\n  directly.\n\n  Libs\n\n  A 'lib' is a named set of resources in classpath whose contents define a\n  library of ClojureScript code. Lib names are symbols and each lib is associated\n  with a ClojureScript namespace. A lib's name also locates its root directory\n  within classpath using Java's package name to classpath-relative path mapping.\n  All resources in a lib should be contained in the directory structure under its\n  root directory. All definitions a lib makes should be in its associated namespace.\n\n  'require loads a lib by loading its root resource. The root resource path\n  is derived from the lib name in the following manner:\n  Consider a lib named by the symbol 'x.y.z; it has the root directory\n  /x/y/, and its root resource is /x/y/z.clj. The root\n  resource should contain code to create the lib's namespace (usually by using\n  the ns macro) and load any additional lib resources.\n\n  Libspecs\n\n  A libspec is a lib name or a vector containing a lib name followed by\n  options expressed as sequential keywords and arguments.\n\n  Recognized options:\n  :as takes a symbol as its argument and makes that symbol an alias to the\n    lib's namespace in the current namespace.\n  :refer takes a list of symbols to refer from the namespace.\n  :refer-macros takes a list of macro symbols to refer from the namespace.\n  :include-macros true causes macros from the namespace to be required.\n  :rename specifies a map from referred var names to different\n    symbols (and can be used to prevent clashes)\n\n\n  Flags\n\n  A flag is a keyword.\n  Recognized flags: :reload, :reload-all, :verbose\n  :reload forces loading of all the identified libs even if they are\n    already loaded\n  :reload-all implies :reload and also forces loading of all libs that the\n    identified libs directly or indirectly load via require or use\n  :verbose triggers printing information about each load, alias, and refer\n\n  Example:\n\n  The following would load the library clojure.string :as string.\n\n  (require '[clojure.string :as string])"
  ([&form &env & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :require args))))))
(core/defn-
  typed-expr?
  [env form allowed-tags]
  (compatible?
    (cljs.analyzer/infer-tag
      env
      (cljs.analyzer/no-warn (cljs.analyzer/analyze env form)))
    allowed-tags))
(clojure.core/defn unchecked-dec-int
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/dec))
        (clojure.core/list x)))))
(clojure.core/defn js-this
  ([&form &env] (core/list (quote js*) "this")))
(clojure.core/defn this-as
  "Defines a scope where JavaScript's implicit \"this\" is bound to the name provided."
  ([&form &env name & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list name)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.core/js-this)))))))))
        body))))
(clojure.core/defn array
  ([&form &env & rest]
    (core/let
      [xs-str
       (core/->>
         (repeat "~{}")
         (take (count rest))
         (interpose ",")
         (apply core/str))]
      (vary-meta
        (list* (quote js*) (core/str "[" xs-str "]") rest)
        assoc
        :tag
        (quote array)))))
(core/defn- string-expr [e] (vary-meta e assoc :tag (quote string)))
(clojure.core/defn load-file*
  ([&form &env f]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote goog/nodeGlobalRequire))
        (clojure.core/list f)))))
(clojure.core/defn bit-set
  ([&form &env x n] (core/list (quote js*) "(~{} | (1 << ~{}))" x n)))
(clojure.core/defn import
  "import-list => (closure-namespace constructor-name-symbols*)\n\n  For each name in constructor-name-symbols, adds a mapping from name to the\n  constructor named by closure-namespace to the current namespace. Use :import in the ns\n  macro in preference to calling this directly."
  ([&form &env & import-symbols-or-lists]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :import import-symbols-or-lists))))))
(clojure.core/defn assert
  "Evaluates expr and throws an exception if it does not evaluate to\n  logical true."
  ([&form &env x]
    (core/when
      *assert*
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/when-not))
          (clojure.core/list x)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote throw))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote js/Error.))
                      (clojure.core/list
                        (core/str
                          "Assert failed: "
                          (core/pr-str x)))))))))))))
  ([&form &env x message]
    (core/when
      *assert*
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/when-not))
          (clojure.core/list x)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote throw))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote js/Error.))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/str))
                            (clojure.core/list "Assert failed: ")
                            (clojure.core/list message)
                            (clojure.core/list "\n")
                            (clojure.core/list
                              (core/pr-str x))))))))))))))))
(clojure.core/defn reify
  "reify creates an object implementing a protocol.\n  reify is a macro with the following structure:\n\n (reify options* specs*)\n\n  Currently there are no options.\n\n  Each spec consists of the protocol name followed by zero\n  or more method bodies:\n\n  protocol\n  (methodName [args+] body)*\n\n  Methods should be supplied for all methods of the desired\n  protocol(s). You can also define overrides for Object methods. Note that\n  the first parameter must be supplied to correspond to the target object\n  ('this' in JavaScript parlance). Note also that recur calls\n  to the method head should *not* pass the target object, it will be supplied\n  automatically and can not be substituted.\n\n  recur works to method heads The method bodies of reify are lexical\n  closures, and can refer to the surrounding local scope:\n\n  (str (let [f \"foo\"]\n       (reify Object\n         (toString [this] f))))\n  == \"foo\"\n\n  (seq (let [f \"foo\"]\n       (reify ISeqable\n         (-seq [this] (seq f)))))\n  == (\"f\" \"o\" \"o\"))\n\n  reify always implements IMeta and IWithMeta and transfers meta\n  data of the form to the created object.\n\n  (meta ^{:k :v} (reify Object (toString [this] \"foo\")))\n  == {:k :v}"
  ([&form &env & impls]
    (core/let
      [t
       (with-meta
         (gensym
           (core/str
             "t_"
             (string/replace
               (core/str (munge ana/*cljs-ns*))
               "."
               "$")))
         {:anonymous true})
       meta-sym
       (gensym "meta")
       this-sym
       (gensym "_")
       locals
       (keys (:locals &env))
       ns
       (core/-> &env :ns :name)
       munge
       comp/munge]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/when-not))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/exists?))
                      (clojure.core/list
                        (symbol (core/str ns) (core/str t))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/deftype))
                      (clojure.core/list t)
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              locals
                              (clojure.core/list meta-sym)))))
                      (clojure.core/list (quote cljs.core/IWithMeta))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote -with-meta))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list this-sym)
                                    (clojure.core/list meta-sym)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote new))
                                  (clojure.core/list t)
                                  locals
                                  (clojure.core/list meta-sym)))))))
                      (clojure.core/list (quote cljs.core/IMeta))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote -meta))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list this-sym)))))
                            (clojure.core/list meta-sym))))
                      impls))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote new))
                (clojure.core/list t)
                locals
                (clojure.core/list
                  (ana/elide-reader-meta (meta &form)))))))))))
(clojure.core/defn *
  ([&form &env] 1)
  ([&form &env x] (core/list (quote js*) "(~{})" x))
  ([&form &env x y] (core/list (quote js*) "(~{} * ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/*))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/*))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn unchecked-remainder-int
  ([&form &env x n]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/mod))
        (clojure.core/list x)
        (clojure.core/list n)))))
(clojure.core/defn or
  "Evaluates exprs one at a time, from left to right. If a form\n  returns a logical true value, or returns that value and doesn't\n  evaluate any of the other expressions, otherwise it returns the\n  value of the last expression. (or) returns nil."
  ([&form &env] nil)
  ([&form &env x] x)
  ([&form &env x & next]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote or__6536__auto__))
                (clojure.core/list x)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote if))
              (clojure.core/list (quote or__6536__auto__))
              (clojure.core/list (quote or__6536__auto__))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/or))
                    next))))))))))
(clojure.core/defn unchecked-add-int
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/+))
        xs))))
(core/defn-
  compatible?
  [inferred-tag allowed-tags]
  (if (set? inferred-tag)
    (clojure.set/subset? inferred-tag allowed-tags)
    (contains? allowed-tags inferred-tag)))
(clojure.core/defn neg?
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/<))
        (clojure.core/list x)
        (clojure.core/list 0)))))
(clojure.core/defn use-macros
  "Similar to use but only for macros."
  ([&form &env & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :use-macros args))))))
(clojure.core/defn nil?
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/coercive-=))
        (clojure.core/list x)
        (clojure.core/list (quote nil))))))
(clojure.core/defn gen-apply-to
  ([&form &env]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote do))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote set!))
              (clojure.core/list (quote *unchecked-if*))
              (clojure.core/list (quote true)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/defn))
              (clojure.core/list (quote apply-to))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote f))
                      (clojure.core/list (quote argc))
                      (clojure.core/list (quote args))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote args))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/seq))
                                  (clojure.core/list
                                    (quote args)))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote if))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/zero?))
                                (clojure.core/list (quote argc)))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote f)))))
                          (clojure.core/list
                            (gen-apply-to-helper)))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote set!))
              (clojure.core/list (quote *unchecked-if*))
              (clojure.core/list (quote false)))))))))
(core/defn-
  annotate-specs
  [annots v [f sigs]]
  (conj
    v
    (vary-meta
      (cons
        f
        (map
          (fn* [p1__7198#] (cons (second p1__7198#) (nnext p1__7198#)))
          sigs))
      merge
      annots)))
(clojure.core/defn string?
  ([&form &env x]
    (bool-expr (core/list (quote js*) "typeof ~{} === 'string'" x))))
(clojure.core/defn array-map
  ([&form &env] (quote (.-EMPTY cljs.core/PersistentArrayMap)))
  ([&form &env & kvs]
    (core/let
      [keys (map first (partition 2 kvs))]
      (if (core/and
            (every?
              (fn*
                [p1__7540#]
                (=
                  (:op (cljs.analyzer/unwrap-quote p1__7540#))
                  :const))
              (map
                (fn*
                  [p1__7541#]
                  (cljs.analyzer/no-warn
                    (cljs.analyzer/analyze &env p1__7541#)))
                keys))
            (= (count (into #{} keys)) (count keys)))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/PersistentArrayMap.))
            (clojure.core/list (quote nil))
            (clojure.core/list (clojure.core// (count kvs) 2))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  kvs)))
            (clojure.core/list (quote nil))))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote .createAsIfByAssoc))
            (clojure.core/list (quote cljs.core/PersistentArrayMap))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  kvs)))))))))
(clojure.core/defn <=
  ([&form &env x] true)
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} <= ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/<=))
              (clojure.core/list x)
              (clojure.core/list y))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/<=))
              (clojure.core/list y)
              more)))))))
(core/defn- to-property [sym] (symbol (core/str "-" sym)))
(clojure.core/defn list
  ([&form &env] (quote (.-EMPTY cljs.core/List)))
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/List.))
        (clojure.core/list (quote nil))
        (clojure.core/list x)
        (clojure.core/list (quote nil))
        (clojure.core/list 1)
        (clojure.core/list (quote nil)))))
  ([&form &env x & xs]
    (core/let
      [cnt (core/inc (count xs))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/List.))
          (clojure.core/list (quote nil))
          (clojure.core/list x)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/list))
                xs)))
          (clojure.core/list cnt)
          (clojure.core/list (quote nil)))))))
(clojure.core/defn coercive-=
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} == ~{})" x y))))
(clojure.core/defn keyword?
  ([&form &env x]
    (bool-expr
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/instance?))
          (clojure.core/list (quote cljs.core/Keyword))
          (clojure.core/list x))))))
(core/defn-
  js-obj*
  [kvs]
  (core/let
    [kvs-str
     (core/->>
       (repeat "~{}:~{}")
       (take (count kvs))
       (interpose ",")
       (apply core/str))]
    (vary-meta
      (list*
        (quote js*)
        (core/str "({" kvs-str "})")
        (apply concat kvs))
      assoc
      :tag
      (quote object))))
(clojure.core/defn unchecked-inc
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/inc))
        (clojure.core/list x)))))
(clojure.core/defn bit-shift-right-zero-fill
  ([&form &env x n] (core/list (quote js*) "(~{} >>> ~{})" x n)))
(clojure.core/defn unsigned-bit-shift-right
  ([&form &env x n] (core/list (quote js*) "(~{} >>> ~{})" x n)))
(clojure.core/defn unchecked-set
  "INTERNAL. Compiles to JavaScript property access using bracket notation. Does\n  not distinguish between object and array types and not subject to compiler\n  static analysis."
  ([&form &env obj key val]
    (core/list (quote js*) "(~{}[~{}] = ~{})" obj key val)))
(clojure.core/defn areduce
  "Reduces an expression across an array a, using an index named idx,\n  and return value named ret, initialized to init, setting ret to the\n  evaluation of expr at each step, returning ret."
  ([&form &env a idx ret init expr]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote a__7616__auto__))
                (clojure.core/list a)
                (clojure.core/list (quote l__7617__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/alength))
                      (clojure.core/list
                        (quote a__7616__auto__)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/loop))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list idx)
                      (clojure.core/list 0)
                      (clojure.core/list ret)
                      (clojure.core/list init)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/<))
                          (clojure.core/list idx)
                          (clojure.core/list
                            (quote l__7617__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote recur))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/inc))
                                (clojure.core/list idx))))
                          (clojure.core/list expr))))
                    (clojure.core/list ret)))))))))))
(clojure.core/defn when-assert ([&form &env x] (core/when *assert* x)))
(clojure.core/defn <
  ([&form &env x] true)
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} < ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/<))
              (clojure.core/list x)
              (clojure.core/list y))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/<))
              (clojure.core/list y)
              more)))))))
(clojure.core/defn es6-iterable
  ([&form &env ty]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/unchecked-set))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote .-prototype))
              (clojure.core/list ty))))
        (clojure.core/list (quote cljs.core/ITER_SYMBOL))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq (clojure.core/concat))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/this-as))
                    (clojure.core/list (quote this__7725__auto__))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote cljs.core/es6-iterator))
                          (clojure.core/list
                            (quote this__7725__auto__)))))))))))))))
(clojure.core/defn unchecked-subtract
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        xs))))
(clojure.core/defn js-inline-comment
  "Emit an inline JavaScript comment."
  ([&form &env comment]
    (core/list (quote js*) (core/str "/**" comment "*/"))))
(core/defn-
  prepare-protocol-masks
  [env impls]
  (core/let
    [resolve
     (partial resolve-var env)
     impl-map
     (->impl-map impls)
     fpp-pbs
     (seq (keep fast-path-protocols (map resolve (keys impl-map))))]
    (if fpp-pbs
      (core/let
        [fpps
         (into
           #{}
           (filter
             (partial contains? fast-path-protocols)
             (map resolve (keys impl-map))))
         parts
         (core/as->
           (group-by first fpp-pbs)
           parts
           (into
             {}
             (map (juxt key (comp (partial map peek) val)) parts))
           (into
             {}
             (map
               (juxt key (comp (partial reduce core/bit-or) val))
               parts)))]
        [fpps
         (reduce
           (core/fn [ps p] (update-in ps [p] (core/fnil identity 0)))
           parts
           (range fast-path-protocol-partitions-count))]))))
(clojure.core/defn unchecked-negate-int
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        (clojure.core/list x)))))
(core/defn-
  ifn-invoke-methods
  [type type-sym [f & meths :as form]]
  (map
    (core/fn
      [meth]
      (core/let
        [arity (count (first meth))]
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote set!))
            (clojure.core/list
              (extend-prefix
                type-sym
                (symbol
                  (core/str "cljs$core$IFn$_invoke$arity$" arity))))
            (clojure.core/list
              (with-meta
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/fn))
                    (clojure.core/list meth)))
                (meta form)))))))
    (map
      (fn* [p1__7128#] (adapt-ifn-invoke-params type p1__7128#))
      meths)))
(core/defn- multi-arity-fn? [fdecl] (core/< 1 (count fdecl)))
(clojure.core/defn unchecked-divide-int
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core//))
        xs))))
(clojure.core/defn loop
  "Evaluates the exprs in a lexical context in which the symbols in\n  the binding-forms are bound to their respective init-exprs or parts\n  therein. Acts as a recur target."
  ([&form &env bindings & body]
    (assert-args
      loop
      (vector? bindings)
      "a vector for its binding"
      (even? (count bindings))
      "an even number of forms in binding vector")
    (core/let
      [db (destructure bindings)]
      (if (= db bindings)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote loop*))
            (clojure.core/list bindings)
            body))
        (core/let
          [vs
           (take-nth 2 (drop 1 bindings))
           bs
           (take-nth 2 bindings)
           gs
           (map (core/fn [b] (if (core/symbol? b) b (gensym))) bs)
           bfs
           (reduce
             (core/fn
               [ret [b v g]]
               (if (core/symbol? b) (conj ret g v) (conj ret g v b g)))
             []
             (map core/vector bs vs gs))]
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/let))
              (clojure.core/list bfs)
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote loop*))
                    (clojure.core/list (vec (interleave gs gs)))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/let))
                          (clojure.core/list (vec (interleave bs gs)))
                          body)))))))))))))
(clojure.core/defn inc
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/+))
        (clojure.core/list x)
        (clojure.core/list 1)))))
(core/defn-
  collect-protocols
  [impls env]
  (core/->>
    impls
    (filter core/symbol?)
    (map
      (fn*
        [p1__7207#]
        (:name
          (cljs.analyzer/resolve-var (dissoc env :locals) p1__7207#))))
    (into #{})))
(clojure.core/defn js-arguments
  ([&form &env] (core/list (quote js*) "arguments")))
(clojure.core/defn undefined?
  "Return true if argument is identical to the JavaScript undefined value."
  ([&form &env x]
    (bool-expr (core/list (quote js*) "(void 0 === ~{})" x))))
(clojure.core/defn doto
  "Evaluates x then calls all of the methods and functions with the\n  value of x supplied at the front of the given arguments.  The forms\n  are evaluated in order.  Returns x.\n\n  (doto (new js/Map) (.set \"a\" 1) (.set \"b\" 2))"
  ([&form &env x & forms]
    (core/let
      [gx (gensym)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list gx)
                  (clojure.core/list x)))))
          (map
            (core/fn
              [f]
              (if (seq? f)
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (first f))
                    (clojure.core/list gx)
                    (next f)))
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list f)
                    (clojure.core/list gx)))))
            forms)
          (clojure.core/list gx))))))
(core/defmethod
  extend-prefix
  :instance
  [tsym sym]
  (clojure.core/seq
    (clojure.core/concat
      (clojure.core/list (quote ..))
      (clojure.core/list tsym)
      (clojure.core/list (to-property sym)))))
(core/defn-
  add-proto-methods*
  [pprefix type type-sym [f & meths :as form]]
  (core/let
    [pf (core/str pprefix (munge (name f)))]
    (if (vector? (first meths))
      (core/let
        [meth meths]
        [(clojure.core/seq
           (clojure.core/concat
             (clojure.core/list (quote set!))
             (clojure.core/list
               (extend-prefix
                 type-sym
                 (core/str pf "$arity$" (count (first meth)))))
             (clojure.core/list
               (with-meta
                 (clojure.core/seq
                   (clojure.core/concat
                     (clojure.core/list (quote cljs.core/fn))
                     (adapt-proto-params type meth)))
                 (meta form)))))])
      (map
        (core/fn
          [[sig & body :as meth]]
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote set!))
              (clojure.core/list
                (extend-prefix
                  type-sym
                  (core/str pf "$arity$" (count sig))))
              (clojure.core/list
                (with-meta
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (adapt-proto-params type meth))))
                  (meta form))))))
        meths))))
(clojure.core/defn coercive-not
  ([&form &env x] (bool-expr (core/list (quote js*) "(!~{})" x))))
(core/defn- bool-expr [e] (vary-meta e assoc :tag (quote boolean)))
(core/defn-
  adapt-ifn-invoke-params
  [type [[this & args :as sig] & body]]
  (clojure.core/seq
    (clojure.core/concat
      (clojure.core/list (vec args))
      (clojure.core/list
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/this-as))
            (clojure.core/list (vary-meta this assoc :tag type))
            body))))))
(core/defmethod
  extend-prefix
  :default
  [tsym sym]
  (with-meta
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ..))
        (clojure.core/list tsym)
        (clojure.core/list (quote -prototype))
        (clojure.core/list (to-property sym))))
    {:extend-type true}))
(core/defn-
  emit-defrecord
  "Do not use this directly - use defrecord"
  [env tagname rname fields impls]
  (core/let
    [hinted-fields
     fields
     fields
     (vec (map (fn* [p1__7224#] (with-meta p1__7224# nil)) fields))
     base-fields
     fields
     pr-open
     (core/str "#" (.getNamespace rname) "." (.getName rname) "{")
     fields
     (conj
       fields
       (quote __meta)
       (quote __extmap)
       (with-meta (quote __hash) {:mutable true}))]
    (core/let
      [gs
       (gensym)
       ksym
       (gensym "k")
       impls
       (concat
         impls
         [(quote IRecord)
          (quote ICloneable)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -clone))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote this__7225__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote new))
                    (clojure.core/list tagname)
                    fields)))))
          (quote IHash)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -hash))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote this__7226__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/caching-hash))
                    (clojure.core/list (quote this__7226__auto__))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/fn))
                          (clojure.core/list
                            (clojure.core/apply
                              clojure.core/vector
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote coll__7227__auto__))))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/bit-xor))
                                (clojure.core/list
                                  (hash
                                    (core/->
                                      rname
                                      comp/munge
                                      core/str)))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          clojure.core/hash-unordered-coll))
                                      (clojure.core/list
                                        (quote
                                          coll__7227__auto__)))))))))))
                    (clojure.core/list (quote __hash)))))))
          (quote IEquiv)
          (core/let
            [this (gensym (quote this)) other (gensym (quote other))]
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote -equiv))
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list this)
                        (clojure.core/list other)))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/and))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/some?))
                            (clojure.core/list other))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/identical?))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote .-constructor))
                                  (clojure.core/list this))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote .-constructor))
                                  (clojure.core/list other)))))))
                      (map
                        (core/fn
                          [field]
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote clojure.core/=))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list (quote ..))
                                    (clojure.core/list this)
                                    (clojure.core/list
                                      (to-property field)))))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list (quote ..))
                                    (clojure.core/list
                                      (with-meta other {:tag tagname}))
                                    (clojure.core/list
                                      (to-property field))))))))
                        base-fields)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote clojure.core/=))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote .-__extmap))
                                  (clojure.core/list this))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote .-__extmap))
                                  (clojure.core/list
                                    (with-meta
                                      other
                                      {:tag tagname}))))))))))))))
          (quote IMeta)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -meta))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote this__7228__auto__))))))
              (clojure.core/list (quote __meta))))
          (quote IWithMeta)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -with-meta))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7229__auto__))
                      (clojure.core/list gs)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote new))
                    (clojure.core/list tagname)
                    (replace {(quote __meta) gs} fields))))))
          (quote ILookup)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -lookup))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7230__auto__))
                      (clojure.core/list (quote k__7231__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/-lookup))
                    (clojure.core/list (quote this__7230__auto__))
                    (clojure.core/list (quote k__7231__auto__))
                    (clojure.core/list (quote nil)))))))
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -lookup))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7232__auto__))
                      (clojure.core/list ksym)
                      (clojure.core/list
                        (quote else__7233__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/case))
                    (clojure.core/list ksym)
                    (mapcat (core/fn [f] [(keyword f) f]) base-fields)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/get))
                          (clojure.core/list (quote __extmap))
                          (clojure.core/list ksym)
                          (clojure.core/list
                            (quote else__7233__auto__))))))))))
          (quote ICounted)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -count))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote this__7234__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/+))
                    (clojure.core/list (count base-fields))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/count))
                          (clojure.core/list (quote __extmap))))))))))
          (quote ICollection)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -conj))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7235__auto__))
                      (clojure.core/list
                        (quote entry__7236__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/vector?))
                          (clojure.core/list
                            (quote entry__7236__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/-assoc))
                          (clojure.core/list
                            (quote this__7235__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/-nth))
                                (clojure.core/list
                                  (quote entry__7236__auto__))
                                (clojure.core/list 0))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/-nth))
                                (clojure.core/list
                                  (quote entry__7236__auto__))
                                (clojure.core/list 1)))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/reduce))
                          (clojure.core/list (quote cljs.core/-conj))
                          (clojure.core/list
                            (quote this__7235__auto__))
                          (clojure.core/list
                            (quote entry__7236__auto__))))))))))
          (quote IAssociative)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -contains-key?))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7237__auto__))
                      (clojure.core/list ksym)))))
              (clojure.core/list
                (if (seq base-fields)
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/case))
                      (clojure.core/list ksym)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (map keyword base-fields))))
                      (clojure.core/list (quote true))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/contains?))
                            (clojure.core/list (quote __extmap))
                            (clojure.core/list ksym))))))
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/contains?))
                      (clojure.core/list (quote __extmap))
                      (clojure.core/list ksym)))))))
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -assoc))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7238__auto__))
                      (clojure.core/list (quote k__7239__auto__))
                      (clojure.core/list gs)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/condp))
                    (clojure.core/list
                      (quote cljs.core/keyword-identical?))
                    (clojure.core/list (quote k__7239__auto__))
                    (mapcat
                      (core/fn
                        [fld]
                        [(keyword fld)
                         (list*
                           (quote new)
                           tagname
                           (replace
                             {fld gs  (quote __hash) nil}
                             fields))])
                      base-fields)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote new))
                          (clojure.core/list tagname)
                          (remove
                            #{(quote __hash) (quote __extmap)}
                            fields)
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/assoc))
                                (clojure.core/list (quote __extmap))
                                (clojure.core/list
                                  (quote k__7239__auto__))
                                (clojure.core/list gs))))
                          (clojure.core/list (quote nil))))))))))
          (quote IMap)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -dissoc))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7240__auto__))
                      (clojure.core/list (quote k__7241__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/contains?))
                          (clojure.core/list
                            (clojure.core/apply
                              clojure.core/hash-set
                              (clojure.core/seq
                                (clojure.core/concat
                                  (map keyword base-fields)))))
                          (clojure.core/list
                            (quote k__7241__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/dissoc))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/-with-meta))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote clojure.core/into))
                                      (clojure.core/list
                                        (clojure.core/apply
                                          clojure.core/hash-map
                                          (clojure.core/seq
                                            (clojure.core/concat))))
                                      (clojure.core/list
                                        (quote this__7240__auto__)))))
                                (clojure.core/list (quote __meta)))))
                          (clojure.core/list
                            (quote k__7241__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote new))
                          (clojure.core/list tagname)
                          (remove
                            #{(quote __hash) (quote __extmap)}
                            fields)
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/not-empty))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote clojure.core/dissoc))
                                      (clojure.core/list
                                        (quote __extmap))
                                      (clojure.core/list
                                        (quote k__7241__auto__))))))))
                          (clojure.core/list (quote nil))))))))))
          (quote ISeqable)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -seq))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote this__7243__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/seq))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/concat))
                          (clojure.core/list
                            (clojure.core/apply
                              clojure.core/vector
                              (clojure.core/seq
                                (clojure.core/concat
                                  (map
                                    (fn*
                                      [p1__7242#]
                                      (core/list
                                        (quote cljs.core/MapEntry.)
                                        (keyword p1__7242#)
                                        p1__7242#
                                        nil))
                                    base-fields)))))
                          (clojure.core/list (quote __extmap))))))))))
          (quote IIterable)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -iterator))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat (clojure.core/list gs)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote RecordIter.))
                    (clojure.core/list 0)
                    (clojure.core/list gs)
                    (clojure.core/list (count base-fields))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (map keyword base-fields)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote if))
                          (clojure.core/list (quote __extmap))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/-iterator))
                                (clojure.core/list (quote __extmap)))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote
                                    clojure.core/nil-iter)))))))))))))
          (quote IPrintWithWriter)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -pr-writer))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7245__auto__))
                      (clojure.core/list (quote writer__7246__auto__))
                      (clojure.core/list
                        (quote opts__7247__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote pr-pair__7248__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/fn))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/vector
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote
                                              keyval__7249__auto__))))))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote
                                            cljs.core/pr-sequential-writer))
                                        (clojure.core/list
                                          (quote writer__7246__auto__))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote js*))
                                              (clojure.core/list
                                                "cljs.core.pr_writer"))))
                                        (clojure.core/list "")
                                        (clojure.core/list " ")
                                        (clojure.core/list "")
                                        (clojure.core/list
                                          (quote opts__7247__auto__))
                                        (clojure.core/list
                                          (quote
                                            keyval__7249__auto__))))))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote cljs.core/pr-sequential-writer))
                          (clojure.core/list
                            (quote writer__7246__auto__))
                          (clojure.core/list
                            (quote pr-pair__7248__auto__))
                          (clojure.core/list pr-open)
                          (clojure.core/list ", ")
                          (clojure.core/list "}")
                          (clojure.core/list
                            (quote opts__7247__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/concat))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/vector
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (map
                                          (fn*
                                            [p1__7244#]
                                            (core/list
                                              (quote cljs.core/vector)
                                              (keyword p1__7244#)
                                              p1__7244#))
                                          base-fields)))))
                                (clojure.core/list
                                  (quote __extmap)))))))))))))
          (quote IKVReduce)
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote -kv-reduce))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote this__7250__auto__))
                      (clojure.core/list (quote f__7251__auto__))
                      (clojure.core/list
                        (quote init__7252__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/reduce))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/fn))
                          (clojure.core/list
                            (clojure.core/apply
                              clojure.core/vector
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote ret__7253__auto__))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/vector
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote k__7254__auto__))
                                          (clojure.core/list
                                            (quote
                                              v__7255__auto__))))))))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote f__7251__auto__))
                                (clojure.core/list
                                  (quote ret__7253__auto__))
                                (clojure.core/list
                                  (quote k__7254__auto__))
                                (clojure.core/list
                                  (quote v__7255__auto__))))))))
                    (clojure.core/list (quote init__7252__auto__))
                    (clojure.core/list
                      (quote this__7250__auto__)))))))])
       [fpps pmasks]
       (prepare-protocol-masks env impls)
       protocols
       (collect-protocols impls env)
       tagname
       (vary-meta
         tagname
         assoc
         :protocols
         protocols
         :skip-protocol-flag
         fpps)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote defrecord*))
                (clojure.core/list tagname)
                (clojure.core/list hinted-fields)
                (clojure.core/list pmasks)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/extend-type))
                      (clojure.core/list tagname)
                      (dt->et tagname impls fields true))))))))))))
(core/defn-
  type-hint-single-arity-sig
  [type-sym sig]
  (list*
    (first sig)
    (type-hint-first-arg type-sym (second sig))
    (nnext sig)))
(clojure.core/defn delay
  "Takes a body of expressions and yields a Delay object that will\n  invoke the body only the first time it is forced (with force or deref/@), and\n  will cache the result and return it on all subsequent force\n  calls."
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote new))
        (clojure.core/list (quote cljs.core/Delay))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq (clojure.core/concat))))
              body)))
        (clojure.core/list (quote nil))))))
(clojure.core/defn caching-hash
  ([&form &env coll hash-fn hash-key]
    (core/assert
      (clojure.core/symbol? hash-key)
      "hash-key is substituted twice")
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote h__6997__auto__))
                (clojure.core/list hash-key)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/if-not))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/nil?))
                    (clojure.core/list (quote h__6997__auto__)))))
              (clojure.core/list (quote h__6997__auto__))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote h__6997__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list hash-fn)
                                  (clojure.core/list coll))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote set!))
                          (clojure.core/list hash-key)
                          (clojure.core/list
                            (quote h__6997__auto__)))))
                    (clojure.core/list
                      (quote h__6997__auto__))))))))))))
(clojure.core/defn unchecked-multiply-int
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/*))
        xs))))
(core/defn-
  gen-apply-to-simple-helper
  [f num-args args]
  (core/let
    [new-arg-sym
     (symbol (core/str "a" num-args))
     proto-name
     (core/str "cljs$core$IFn$_invoke$arity$" (core/inc num-args))
     proto-prop
     (symbol (core/str ".-" proto-name))
     proto-inv
     (symbol (core/str "." proto-name))
     next-sym
     (symbol (core/str "next_" num-args))
     all-args
     (mapv
       (fn* [p1__7694#] (symbol (core/str "a" p1__7694#)))
       (range (core/inc num-args)))]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list new-arg-sym)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/-first))
                      (clojure.core/list args))))
                (clojure.core/list next-sym)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/next))
                      (clojure.core/list args))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote if))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/nil?))
                    (clojure.core/list next-sym))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list proto-prop)
                          (clojure.core/list f))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list proto-inv)
                          (clojure.core/list f)
                          all-args)))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote .call))
                          (clojure.core/list f)
                          (clojure.core/list f)
                          all-args))))))
              (clojure.core/list
                (if (core/<= 19 num-args)
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/let))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote arr__7695__auto__))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/array))
                                    all-args)))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/loop))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote s__7696__auto__))
                                    (clojure.core/list next-sym)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/when))
                                  (clojure.core/list
                                    (quote s__7696__auto__))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list (quote do))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote .push))
                                              (clojure.core/list
                                                (quote
                                                  arr__7695__auto__))
                                              (clojure.core/list
                                                (clojure.core/seq
                                                  (clojure.core/concat
                                                    (clojure.core/list
                                                      (quote
                                                        cljs.core/-first))
                                                    (clojure.core/list
                                                      (quote
                                                        s__7696__auto__))))))))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote recur))
                                              (clojure.core/list
                                                (clojure.core/seq
                                                  (clojure.core/concat
                                                    (clojure.core/list
                                                      (quote
                                                        cljs.core/next))
                                                    (clojure.core/list
                                                      (quote
                                                        s__7696__auto__)))))))))))))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote .apply))
                            (clojure.core/list f)
                            (clojure.core/list f)
                            (clojure.core/list
                              (quote arr__7695__auto__)))))))
                  (gen-apply-to-simple-helper
                    f
                    (core/inc num-args)
                    next-sym))))))))))
(clojure.core/defn js-fn?
  ([&form &env x]
    (bool-expr (core/list (quote js*) "typeof ~{} === 'function'" x))))
(clojure.core/defn js-delete
  ([&form &env obj key]
    (core/list (quote js*) "delete ~{}[~{}]" obj key)))
(clojure.core/defn bit-shift-right
  ([&form &env x n] (core/list (quote js*) "(~{} >> ~{})" x n)))
(clojure.core/defn refer-clojure
  "Refers to all the public vars of `cljs.core`, subject to\n  filters.\n  Filters can include at most one each of:\n\n  :exclude list-of-symbols\n  :rename map-of-fromsymbol-tosymbol\n\n  Filters can be used to select a subset, via exclusion, or to provide a mapping\n  to a symbol different from the var's name, in order to prevent clashes."
  ([&form &env & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :refer-clojure args))))))
(clojure.core/defn int
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/bit-or))
        (clojure.core/list x)
        (clojure.core/list 0)))))
(clojure.core/defn truth_
  ([&form &env x]
    (core/assert (core/symbol? x) "x is substituted twice")
    (core/list (quote js*) "(~{} != null && ~{} !== false)" x x)))
(core/defn-
  proto-assign-impls
  [env resolve type-sym type [p sigs]]
  (update-protocol-var p type env)
  (core/let
    [psym
     (resolve p)
     pprefix
     (protocol-prefix psym)
     skip-flag
     (set (core/-> type-sym meta :skip-protocol-flag))]
    (if (= p (quote Object))
      (add-obj-methods type type-sym sigs)
      (concat
        (core/when-not
          (skip-flag psym)
          [(clojure.core/seq
             (clojure.core/concat
               (clojure.core/list (quote set!))
               (clojure.core/list (extend-prefix type-sym pprefix))
               (clojure.core/list
                 (quote cljs.core/PROTOCOL_SENTINEL))))])
        (mapcat
          (core/fn
            [sig]
            (if (= psym (quote cljs.core/IFn))
              (add-ifn-methods type type-sym sig)
              (add-proto-methods* pprefix type type-sym sig)))
          sigs)))))
(clojure.core/defn +
  ([&form &env] 0)
  ([&form &env x] (core/list (quote js*) "(~{})" x))
  ([&form &env x y] (core/list (quote js*) "(~{} + ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/+))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/+))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(core/defn-
  build-map-factory
  [rsym rname fields]
  (core/let
    [fn-name
     (with-meta
       (symbol (core/str (quote map->) rsym))
       (assoc (meta rsym) :factory :map))
     docstring
     (core/str
       "Factory function for "
       rname
       ", taking a map of keywords to field values.")
     ms
     (gensym)
     ks
     (map keyword fields)
     getters
     (map
       (core/fn
         [k]
         (clojure.core/seq
           (clojure.core/concat
             (clojure.core/list k)
             (clojure.core/list ms))))
       ks)]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/defn))
        (clojure.core/list fn-name)
        (clojure.core/list docstring)
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat (clojure.core/list ms)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/let))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote extmap__7272__auto__))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/cond->>))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/dissoc))
                                  (clojure.core/list ms)
                                  ks)))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/record?))
                                  (clojure.core/list ms))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/into))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/hash-map
                                      (clojure.core/seq
                                        (clojure.core/concat))))))))))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote new))
                    (clojure.core/list rname)
                    getters
                    (clojure.core/list (quote nil))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote clojure.core/not-empty))
                          (clojure.core/list
                            (quote extmap__7272__auto__)))))
                    (clojure.core/list (quote nil))))))))))))
(clojure.core/defn specify!
  "Identical to reify but mutates its first argument."
  ([&form &env expr & impls]
    (core/let
      [x (with-meta (gensym "x") {:extend :instance})]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list x)
                  (clojure.core/list expr)))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/extend-type))
                (clojure.core/list x)
                impls)))
          (clojure.core/list x))))))
(clojure.core/defn defmethod
  "Creates and installs a new method of multimethod associated with dispatch-value. "
  ([&form &env multifn dispatch-val & fn-tail]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-add-method))
        (clojure.core/list
          (with-meta multifn {:tag (quote cljs.core/MultiFn)}))
        (clojure.core/list dispatch-val)
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/fn))
              fn-tail)))))))
(clojure.core/defn bit-shift-left
  ([&form &env x n] (core/list (quote js*) "(~{} << ~{})" x n)))
(clojure.core/defn pos?
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/>))
        (clojure.core/list x)
        (clojure.core/list 0)))))
(core/defn-
  type-hint-impl-map
  [type-sym impl-map]
  (reduce-kv
    (core/fn
      [m proto sigs]
      (assoc m proto (map (partial type-hint-sigs type-sym) sigs)))
    {}
    impl-map))
(clojure.core/defn unchecked-dec
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/dec))
        (clojure.core/list x)))))
(clojure.core/defn -
  ([&form &env x] (core/list (quote js*) "(- ~{})" x))
  ([&form &env x y] (core/list (quote js*) "(~{} - ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/-))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn unchecked-negate
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        (clojure.core/list x)))))
(clojure.core/defn require-macros
  "Similar to require but only for macros."
  ([&form &env & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :require-macros args))))))
(clojure.core/defn unchecked-add
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/+))
        xs))))
(clojure.core/defn gen-apply-to-simple
  ([&form &env f num-args args]
    (gen-apply-to-simple-helper f num-args args)))
(core/defn-
  build-positional-factory
  [rsym rname fields]
  (core/let
    [fn-name
     (with-meta
       (symbol (core/str (quote ->) rsym))
       (assoc (meta rsym) :factory :positional))
     docstring
     (core/str "Positional factory function for " rname ".")
     field-values
     (if (core/-> rsym meta :internal-ctor)
       (conj fields nil nil nil)
       fields)]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/defn))
        (clojure.core/list fn-name)
        (clojure.core/list docstring)
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq (clojure.core/concat fields))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote new))
              (clojure.core/list rname)
              field-values)))))))
(core/defn-
  const?
  [env x]
  (core/let
    [m (core/and (core/list? x) (ana/resolve-var env (last x)))]
    (core/when m (core/get m :const))))
(clojure.core/defn let
  "binding => binding-form init-expr\n  binding-form => name, or destructuring-form\n  destructuring-form => map-destructure-form, or seq-destructure-form\n\n  Evaluates the exprs in a lexical context in which the symbols in\n  the binding-forms are bound to their respective init-exprs or parts\n  therein.\n\n  See https://clojure.org/reference/special_forms#binding-forms for\n  more information about destructuring."
  ([&form &env bindings & body]
    (assert-args
      let
      (vector? bindings)
      "a vector for its binding"
      (even? (count bindings))
      "an even number of forms in binding vector")
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote let*))
        (clojure.core/list (destructure bindings))
        body))))
(core/defn-
  adapt-obj-params
  [type [[this & args :as sig] & body]]
  (core/list
    (vec args)
    (list* (quote this-as) (vary-meta this assoc :tag type) body)))
(clojure.core/defn use
  "Like require, but referring vars specified by the mandatory\n  :only option.\n\n  Example:\n\n  The following would load the library clojure.set while referring\n  the intersection var.\n\n  (use '[clojure.set :only [intersection]])"
  ([&form &env & args]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote ns*))
        (clojure.core/list (cons :use args))))))
(core/defn-
  adapt-ifn-params
  [type [[this & args :as sig] & body]]
  (core/let
    [self-sym (with-meta (quote self__) {:tag type})]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (vec (cons self-sym args)))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/this-as))
              (clojure.core/list self-sym)
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list this)
                            (clojure.core/list self-sym)))))
                    body))))))))))
(core/defn-
  variadic-fn?
  [fdecl]
  (core/and (= 1 (count fdecl)) (some (quote #{&}) (ffirst fdecl))))
(clojure.core/defn unchecked-inc-int
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/inc))
        (clojure.core/list x)))))
(clojure.core/defn unchecked-subtract-int
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/-))
        xs))))
(clojure.core/defn copy-arguments
  ([&form &env dest]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote len__7864__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/alength))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/js-arguments))))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/loop))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote i__7865__auto__))
                      (clojure.core/list 0)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/when))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/<))
                          (clojure.core/list (quote i__7865__auto__))
                          (clojure.core/list
                            (quote len__7864__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote .push))
                          (clojure.core/list dest)
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/unchecked-get))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.core/js-arguments)))))
                                (clojure.core/list
                                  (quote i__7865__auto__))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote recur))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/inc))
                                (clojure.core/list
                                  (quote
                                    i__7865__auto__))))))))))))))))))
(clojure.core/defn mask
  ([&form &env hash shift]
    (core/list (quote js*) "((~{} >>> ~{}) & 0x01f)" hash shift)))
(clojure.core/defn some?
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/not))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/nil?))
              (clojure.core/list x))))))))
(clojure.core/defn number?
  ([&form &env x]
    (bool-expr (core/list (quote js*) "typeof ~{} === 'number'" x))))
(core/defn-
  adapt-proto-params
  [type [[this & args :as sig] & body]]
  (core/let
    [this' (vary-meta this assoc :tag type)]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (vec (cons this' args)))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/this-as))
              (clojure.core/list this')
              body)))))))
(core/defn-
  add-obj-methods
  [type type-sym sigs]
  (map
    (core/fn
      [[f & meths :as form]]
      (core/let
        [[f meths]
         (if (vector? (first meths)) [f [(rest form)]] [f meths])]
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote set!))
            (clojure.core/list (extend-prefix type-sym f))
            (clojure.core/list
              (with-meta
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/fn))
                    (map
                      (fn*
                        [p1__7115#]
                        (adapt-obj-params type p1__7115#))
                      meths)))
                (meta form)))))))
    sigs))
(core/defn-
  gen-apply-to-helper
  ([] (gen-apply-to-helper 1))
  ([n]
    (if (core/<= n 20)
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (cs (core/dec n)))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/-first))
                        (clojure.core/list (quote args)))))
                  (clojure.core/list (quote args))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/-rest))
                        (clojure.core/list (quote args)))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote if))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/==))
                      (clojure.core/list (quote argc))
                      (clojure.core/list n))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote f))
                      (take n cs))))
                (clojure.core/list
                  (gen-apply-to-helper (core/inc n))))))))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote throw))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote js/Error.))
                (clojure.core/list
                  "Only up to 20 arguments supported on functions")))))))))
(clojure.core/defn false?
  ([&form &env x]
    (bool-expr (core/list (quote js*) "~{} === false" x))))
(clojure.core/defn unchecked-multiply
  ([&form &env & xs]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/*))
        xs))))
(clojure.core/defn bit-flip
  ([&form &env x n] (core/list (quote js*) "(~{} ^ (1 << ~{}))" x n)))
(clojure.core/defn lazy-seq
  "Takes a body of expressions that returns an ISeq or nil, and yields\n  a ISeqable object that will invoke the body only the first time seq\n  is called, and will cache the result and return it on all subsequent\n  seq calls."
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote new))
        (clojure.core/list (quote cljs.core/LazySeq))
        (clojure.core/list (quote nil))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq (clojure.core/concat))))
              body)))
        (clojure.core/list (quote nil))
        (clojure.core/list (quote nil))))))
(clojure.core/defn str
  ([&form &env] "")
  ([&form &env x]
    (if (typed-expr? &env x (quote #{string}))
      x
      (string-expr
        (core/list
          (quote js*)
          "cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})"
          x))))
  ([&form &env x & ys]
    (core/let
      [interpolate
       (core/fn
         [x]
         (if (typed-expr? &env x (quote #{string clj-nil}))
           "~{}"
           "cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})"))
       strs
       (core/->>
         (core/list* x ys)
         (map interpolate)
         (interpose ",")
         (apply core/str))]
      (string-expr
        (list* (quote js*) (core/str "[" strs "].join('')") x ys)))))
(clojure.core/defn defmulti
  "Creates a new multimethod with the associated dispatch function.\n  The docstring and attribute-map are optional.\n\n  Options are key-value pairs and may be one of:\n    :default    the default dispatch value, defaults to :default\n    :hierarchy  the isa? hierarchy to use for dispatching\n                defaults to the global hierarchy"
  {:arglists
   (quote ([name docstring? attr-map? dispatch-fn & options]))}
  ([&form &env mm-name & options]
    (core/let
      [docstring
       (if (core/string? (first options)) (first options) nil)
       options
       (if (core/string? (first options)) (next options) options)
       m
       (if (map? (first options)) (first options) {})
       options
       (if (map? (first options)) (next options) options)
       dispatch-fn
       (first options)
       options
       (next options)
       m
       (if docstring (assoc m :doc docstring) m)
       m
       (if (meta mm-name) (conj (meta mm-name) m) m)
       mm-ns
       (core/-> &env :ns :name core/str)]
      (core/when
        (= (count options) 1)
        (throw
          (Exception.
            "The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value)")))
      (core/let
        [options
         (apply core/hash-map options)
         default
         (core/get options :default :default)]
        (check-valid-options options :default :hierarchy)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/defonce))
            (clojure.core/list (with-meta mm-name m))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/let))
                  (clojure.core/list
                    (clojure.core/apply
                      clojure.core/vector
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote method-table__7633__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/atom))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat)))))))
                          (clojure.core/list
                            (quote prefer-table__7634__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/atom))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat)))))))
                          (clojure.core/list
                            (quote method-cache__7635__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/atom))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat)))))))
                          (clojure.core/list
                            (quote cached-hierarchy__7636__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/atom))
                                (clojure.core/list
                                  (clojure.core/apply
                                    clojure.core/hash-map
                                    (clojure.core/seq
                                      (clojure.core/concat)))))))
                          (clojure.core/list
                            (quote hierarchy__7637__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/get))
                                (clojure.core/list options)
                                (clojure.core/list :hierarchy)
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote js*))
                                            (clojure.core/list
                                              "cljs.core.get_global_hierarchy"))))))))))))))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/MultiFn.))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/symbol))
                              (clojure.core/list mm-ns)
                              (clojure.core/list (name mm-name)))))
                        (clojure.core/list dispatch-fn)
                        (clojure.core/list default)
                        (clojure.core/list
                          (quote hierarchy__7637__auto__))
                        (clojure.core/list
                          (quote method-table__7633__auto__))
                        (clojure.core/list
                          (quote prefer-table__7634__auto__))
                        (clojure.core/list
                          (quote method-cache__7635__auto__))
                        (clojure.core/list
                          (quote
                            cached-hierarchy__7636__auto__))))))))))))))
(clojure.core/defn case
  "Takes an expression, and a set of clauses.\n\n  Each clause can take the form of either:\n\n  test-constant result-expr\n\n  (test-constant1 ... test-constantN)  result-expr\n\n  The test-constants are not evaluated. They must be compile-time\n  literals, and need not be quoted.  If the expression is equal to a\n  test-constant, the corresponding result-expr is returned. A single\n  default expression can follow the clauses, and its value will be\n  returned if no clause matches. If no default expression is provided\n  and no clause matches, an Error is thrown.\n\n  Unlike cond and condp, case does a constant-time dispatch, the\n  clauses are not considered sequentially.  All manner of constant\n  expressions are acceptable in case, including numbers, strings,\n  symbols, keywords, and (ClojureScript) composites thereof. Note that since\n  lists are used to group multiple constants that map to the same\n  expression, a vector can be used to match a list if needed. The\n  test-constants need not be all of the same type."
  ([&form &env e & clauses]
    (core/let
      [esym
       (gensym)
       default
       (if (odd? (count clauses))
         (last clauses)
         (clojure.core/seq
           (clojure.core/concat
             (clojure.core/list (quote throw))
             (clojure.core/list
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote js/Error.))
                   (clojure.core/list
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list (quote cljs.core/str))
                         (clojure.core/list "No matching clause: ")
                         (clojure.core/list esym))))))))))
       env
       &env
       pairs
       (reduce
         (core/fn
           [m [test expr]]
           (core/cond
             (seq? test)
             (reduce
               (core/fn
                 [m test]
                 (core/let
                   [test
                    (if (core/symbol? test)
                      (core/list (quote quote) test)
                      test)]
                   (assoc-test m test expr env)))
               m
               test)
             (core/symbol? test)
             (assoc-test m (core/list (quote quote) test) expr env)
             :else
             (assoc-test m test expr env)))
         {}
         (partition 2 clauses))
       tests
       (keys pairs)]
      (core/cond
        (every?
          (some-fn
            core/number?
            core/string?
            core/char?
            (fn* [p1__7413#] (const? env p1__7413#)))
          tests)
        (core/let
          [no-default
           (if (odd? (count clauses)) (butlast clauses) clauses)
           tests
           (mapv
             (fn*
               [p1__7414#]
               (if (seq? p1__7414#) (vec p1__7414#) [p1__7414#]))
             (take-nth 2 no-default))
           thens
           (vec (take-nth 2 (drop 1 no-default)))]
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/let))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list esym)
                      (clojure.core/list e)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote case*))
                    (clojure.core/list esym)
                    (clojure.core/list tests)
                    (clojure.core/list thens)
                    (clojure.core/list default)))))))
        (every? core/keyword? tests)
        (core/let
          [no-default
           (if (odd? (count clauses)) (butlast clauses) clauses)
           kw-str
           (fn* [p1__7415#] (.substring (core/str p1__7415#) 1))
           tests
           (mapv
             (fn*
               [p1__7416#]
               (if (seq? p1__7416#)
                 (mapv kw-str p1__7416#)
                 [(kw-str p1__7416#)]))
             (take-nth 2 no-default))
           thens
           (vec (take-nth 2 (drop 1 no-default)))]
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/let))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list esym)
                      (clojure.core/list e)
                      (clojure.core/list esym)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote if))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/keyword?))
                                  (clojure.core/list esym))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote .-fqn))
                                  (clojure.core/list
                                    (vary-meta
                                      esym
                                      assoc
                                      :tag
                                      (quote cljs.core/Keyword))))))
                            (clojure.core/list (quote nil)))))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote case*))
                    (clojure.core/list esym)
                    (clojure.core/list tests)
                    (clojure.core/list thens)
                    (clojure.core/list default)))))))
        :else
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/let))
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list esym)
                    (clojure.core/list e)))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/cond))
                  (mapcat
                    (core/fn
                      [[m c]]
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote cljs.core/=))
                                (clojure.core/list m)
                                (clojure.core/list esym))))
                          (clojure.core/list c))))
                    pairs)
                  (clojure.core/list :else)
                  (clojure.core/list default))))))))))
(core/defn
  dt->et
  ([type specs fields] (dt->et type specs fields false))
  ([type specs fields inline]
    (core/let
      [annots
       {:cljs.analyzer/typetype:cljs.analyzer/protocol-impltrue:cljs.analyzer/protocol-inline         inline}](core/loop[ret[]specs   specs](if(
        seqspecs)(core/let[p
        (firstspecs)ret
          (core/->(
            conj            retp)( into(reduce         (partial         annotate-specs          annots)[] (group-by         first
                 (take-while                seq?(nextspecs))))))specs(drop-while               seq?                  (nextspecs))](recurretspecs ))ret)))))
(clojure.core/defn defonce
  "defs name to have the root value of init iff the named var has no root value,\n  else init is unevaluated"
  ([&form &env x init]
    (core/let
      [qualified
       (if (namespace x)
         x
         (symbol (core/str (core/-> &env :ns :name)) (name x)))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/when-not))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/exists?))
                (clojure.core/list qualified))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote def))
                (clojure.core/list x)
                (clojure.core/list init)))))))))
(core/defn-
  variadic-fn
  [name meta [[arglist & body :as method] :as fdecl] emit-var?]
  (core/letfn
    [(dest-args
       [c]
       (map
         (core/fn
           [n]
           (clojure.core/seq
             (clojure.core/concat
               (clojure.core/list (quote cljs.core/unchecked-get))
               (clojure.core/list
                 (clojure.core/seq
                   (clojure.core/concat
                     (clojure.core/list
                       (quote cljs.core/js-arguments)))))
               (clojure.core/list n))))
         (range c)))]
    (core/let
      [rname
       (symbol (core/str ana/*cljs-ns*) (core/str name))
       sig
       (remove (quote #{&}) arglist)
       c-1
       (core/dec (count sig))
       macro?
       (:macro meta)
       mfa
       (core/cond-> c-1 macro? (core/- 2))
       meta
       (assoc
         meta
         :top-fn
         {:variadic? true 
          :fixed-arity mfa 
          :max-fixed-arity mfa 
          :method-params
          (core/cond-> [sig] macro? elide-implicit-macro-args) 
          :arglists
          (core/cond->
            (core/list arglist)
            macro?
            elide-implicit-macro-args) 
          :arglists-meta (doall (map meta [arglist]))})
       name
       (with-meta name meta)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote def))
                (clojure.core/list name)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote var_args))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/let))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote args__7874__auto__))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote
                                              cljs.core/array)))))))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/copy-arguments))
                                  (clojure.core/list
                                    (quote args__7874__auto__)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/let))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/vector
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote
                                              argseq__7875__auto__))
                                          (clojure.core/list
                                            (clojure.core/seq
                                              (clojure.core/concat
                                                (clojure.core/list
                                                  (quote
                                                    cljs.core/when))
                                                (clojure.core/list
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        (quote
                                                          cljs.core/<))
                                                      (clojure.core/list
                                                        c-1)
                                                      (clojure.core/list
                                                        (clojure.core/seq
                                                          (clojure.core/concat
                                                            (clojure.core/list
                                                              (quote
                                                                cljs.core/alength))
                                                            (clojure.core/list
                                                              (quote
                                                                args__7874__auto__))))))))
                                                (clojure.core/list
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        (quote new))
                                                      (clojure.core/list
                                                        (clojure.core/with-meta
                                                          (quote
                                                            cljs.core/IndexedSeq)
                                                          (clojure.core/apply
                                                            clojure.core/hash-map
                                                            (clojure.core/seq
                                                              (clojure.core/concat
                                                                (clojure.core/list
                                                                  :cljs.analyzer/no-resolve)
                                                                (clojure.core/list
                                                                  (quote
                                                                    true)))))))
                                                      (clojure.core/list
                                                        (clojure.core/seq
                                                          (clojure.core/concat
                                                            (clojure.core/list
                                                              (quote
                                                                .slice))
                                                            (clojure.core/list
                                                              (quote
                                                                args__7874__auto__))
                                                            (clojure.core/list
                                                              c-1))))
                                                      (clojure.core/list
                                                        0)
                                                      (clojure.core/list
                                                        (quote
                                                          nil))))))))))))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list (quote .))
                                        (clojure.core/list rname)
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote
                                                  cljs$core$IFn$_invoke$arity$variadic))
                                              (dest-args c-1)
                                              (clojure.core/list
                                                (quote
                                                  argseq__7875__auto__))))))))))))))))))))
          (clojure.core/list (variadic-fn* name method))
          (clojure.core/list
            (core/when
              emit-var?
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote var))
                  (clojure.core/list name))))))))))
(clojure.core/defn resolve
  "Returns the var to which a symbol will be resolved in the namespace else nil."
  ([&form &env quoted-sym]
    (core/assert
      (core/and (seq? quoted-sym) (= (quote quote) (first quoted-sym)))
      "Argument to resolve must be a quoted symbol")
    (core/let
      [sym
       (second quoted-sym)
       env
       &env
       [var meta]
       (try
         (core/let
           [var
            (ana/resolve-var env sym (ana/confirm-var-exists-throw))]
           [var (ana/var-meta var)])
         (catch Throwable t [(ana/resolve-var env sym) nil]))
       resolved
       (vary-meta (:name var) assoc :cljs.analyzer/no-resolve true)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/when))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/exists?))
                (clojure.core/list resolved))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/Var.))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq (clojure.core/concat))))
                      (clojure.core/list resolved))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote quote))
                      (clojure.core/list resolved))))
                (clojure.core/list meta)))))))))
(clojure.core/defn extend-type
  "Extend a type to a series of protocols. Useful when you are\n  supplying the definitions explicitly inline. Propagates the\n  type as a type hint on the first argument of all fns.\n\n  type-sym may be\n\n   * default, meaning the definitions will apply for any value,\n     unless an extend-type exists for one of the more specific\n     cases below.\n   * nil, meaning the definitions will apply for the nil value.\n   * any of object, boolean, number, string, array, or function,\n     indicating the definitions will apply for values of the\n     associated base JavaScript types. Note that, for example,\n     string should be used instead of js/String.\n   * a JavaScript type not covered by the previous list, such\n     as js/RegExp.\n   * a type defined by deftype or defrecord.\n\n  (extend-type MyType\n    ICounted\n    (-count [c] ...)\n    Foo\n    (bar [x y] ...)\n    (baz ([x] ...) ([x y] ...) ...)"
  ([&form &env type-sym & impls]
    (core/let
      [env
       &env
       _
       (validate-impls env impls)
       resolve
       (partial resolve-var env)
       impl-map
       (->impl-map impls)
       impl-map
       (if ((quote #{boolean number}) type-sym)
         (type-hint-impl-map type-sym impl-map)
         impl-map)
       [type assign-impls]
       (core/if-let
         [type (base-type type-sym)]
         [type base-assign-impls]
         [(resolve type-sym) proto-assign-impls])]
      (core/when
        (core/and
          (:extending-base-js-type cljs.analyzer/*cljs-warnings*)
          (js-base-type type-sym))
        (cljs.analyzer/warning
          :extending-base-js-type
          env
          {:current-symbol type-sym 
           :suggested-symbol (js-base-type type-sym)}))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (mapcat
            (fn*
              [p1__7182#]
              (assign-impls env resolve type-sym type p1__7182#))
            impl-map))))))
(core/defn-
  multi-arity-fn
  [name meta fdecl emit-var?]
  (core/letfn
    [(dest-args
       [c]
       (map
         (core/fn
           [n]
           (clojure.core/seq
             (clojure.core/concat
               (clojure.core/list (quote cljs.core/unchecked-get))
               (clojure.core/list
                 (clojure.core/seq
                   (clojure.core/concat
                     (clojure.core/list
                       (quote cljs.core/js-arguments)))))
               (clojure.core/list n))))
         (range c)))
     (fixed-arity
       [rname sig]
       (core/let
         [c (count sig)]
         [c
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote .))
              (clojure.core/list rname)
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list
                      (symbol
                        (core/str "cljs$core$IFn$_invoke$arity$" c)))
                    (dest-args c))))))]))
     (fn-method
       [name [sig & body :as method]]
       (if (some (quote #{&}) sig)
         (variadic-fn* name method false)
         (clojure.core/seq
           (clojure.core/concat
             (clojure.core/list (quote set!))
             (clojure.core/list
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote .))
                   (clojure.core/list
                     (vary-meta
                       name
                       update
                       :top-fn
                       merge
                       {:variadic? false  :fixed-arity (count sig)}))
                   (clojure.core/list
                     (symbol
                       (core/str
                         "-cljs$core$IFn$_invoke$arity$"
                         (count sig)))))))
             (clojure.core/list
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote cljs.core/fn))
                   (clojure.core/list method))))))))]
    (core/let
      [rname
       (symbol (core/str ana/*cljs-ns*) (core/str name))
       arglists
       (map first fdecl)
       macro?
       (:macro meta)
       varsig?
       (fn* [p1__7891#] (boolean (some (quote #{&}) p1__7891#)))
       {sigs false  var-sigs true}
       (group-by varsig? arglists)
       variadic?
       (core/pos? (core/count var-sigs))
       variadic-params
       (if variadic?
         (core/cond->
           (remove (quote #{&}) (first var-sigs))
           true
           core/count
           macro?
           (core/- 2))
         0)
       maxfa
       (apply
         core/max
         (concat
           (map count sigs)
           [(core/- (count (first var-sigs)) 2)]))
       mfa
       (core/cond-> maxfa macro? (core/- 2))
       meta
       (assoc
         meta
         :top-fn
         {:variadic? variadic? 
          :fixed-arity mfa 
          :max-fixed-arity mfa 
          :method-params
          (core/cond-> sigs macro? elide-implicit-macro-args) 
          :arglists
          (core/cond-> arglists macro? elide-implicit-macro-args) 
          :arglists-meta (doall (map meta arglists))})
       args-sym
       (gensym "args")
       param-counts
       (map count arglists)
       name
       (with-meta name meta)]
      (core/when
        (core/< 1 (count var-sigs))
        (ana/warning :multiple-variadic-overloads {} {:name name}))
      (core/when
        (core/and
          (core/pos? variadic-params)
          (not (core/== variadic-params (core/+ 1 mfa))))
        (ana/warning :variadic-max-arity {} {:name name}))
      (core/when
        (not= (distinct param-counts) param-counts)
        (ana/warning :overload-arity {} {:name name}))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote def))
                (clojure.core/list name)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/fn))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote var_args))))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/case))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/alength))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote
                                            cljs.core/js-arguments))))))))
                            (mapcat
                              (fn*
                                [p1__7892#]
                                (fixed-arity rname p1__7892#))
                              sigs)
                            (clojure.core/list
                              (if variadic?
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/let))
                                    (clojure.core/list
                                      (clojure.core/apply
                                        clojure.core/vector
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote
                                                args-arr__7893__auto__))
                                            (clojure.core/list
                                              (clojure.core/seq
                                                (clojure.core/concat
                                                  (clojure.core/list
                                                    (quote
                                                      cljs.core/array)))))))))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote
                                              cljs.core/copy-arguments))
                                          (clojure.core/list
                                            (quote
                                              args-arr__7893__auto__)))))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote cljs.core/let))
                                          (clojure.core/list
                                            (clojure.core/apply
                                              clojure.core/vector
                                              (clojure.core/seq
                                                (clojure.core/concat
                                                  (clojure.core/list
                                                    (quote
                                                      argseq__7894__auto__))
                                                  (clojure.core/list
                                                    (clojure.core/seq
                                                      (clojure.core/concat
                                                        (clojure.core/list
                                                          (quote new))
                                                        (clojure.core/list
                                                          (clojure.core/with-meta
                                                            (quote
                                                              cljs.core/IndexedSeq)
                                                            (clojure.core/apply
                                                              clojure.core/hash-map
                                                              (clojure.core/seq
                                                                (clojure.core/concat
                                                                  (clojure.core/list
                                                                    :cljs.analyzer/no-resolve)
                                                                  (clojure.core/list
                                                                    (quote
                                                                      true)))))))
                                                        (clojure.core/list
                                                          (clojure.core/seq
                                                            (clojure.core/concat
                                                              (clojure.core/list
                                                                (quote
                                                                  .slice))
                                                              (clojure.core/list
                                                                (quote
                                                                  args-arr__7893__auto__))
                                                              (clojure.core/list
                                                                maxfa))))
                                                        (clojure.core/list
                                                          0)
                                                        (clojure.core/list
                                                          (quote
                                                            nil)))))))))
                                          (clojure.core/list
                                            (clojure.core/seq
                                              (clojure.core/concat
                                                (clojure.core/list
                                                  (quote .))
                                                (clojure.core/list
                                                  rname)
                                                (clojure.core/list
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        (quote
                                                          cljs$core$IFn$_invoke$arity$variadic))
                                                      (dest-args maxfa)
                                                      (clojure.core/list
                                                        (quote
                                                          argseq__7894__auto__)))))))))))))
                                (if
                                  (:macro meta)
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list (quote throw))
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote js/Error.))
                                            (clojure.core/list
                                              (clojure.core/seq
                                                (clojure.core/concat
                                                  (clojure.core/list
                                                    (quote
                                                      cljs.core/str))
                                                  (clojure.core/list
                                                    "Invalid arity: ")
                                                  (clojure.core/list
                                                    (clojure.core/seq
                                                      (clojure.core/concat
                                                        (clojure.core/list
                                                          (quote
                                                            cljs.core/-))
                                                        (clojure.core/list
                                                          (clojure.core/seq
                                                            (clojure.core/concat
                                                              (clojure.core/list
                                                                (quote
                                                                  cljs.core/alength))
                                                              (clojure.core/list
                                                                (clojure.core/seq
                                                                  (clojure.core/concat
                                                                    (clojure.core/list
                                                                      (quote
                                                                        cljs.core/js-arguments))))))))
                                                        (clojure.core/list
                                                          2))))))))))))
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list (quote throw))
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote js/Error.))
                                            (clojure.core/list
                                              (clojure.core/seq
                                                (clojure.core/concat
                                                  (clojure.core/list
                                                    (quote
                                                      cljs.core/str))
                                                  (clojure.core/list
                                                    "Invalid arity: ")
                                                  (clojure.core/list
                                                    (clojure.core/seq
                                                      (clojure.core/concat
                                                        (clojure.core/list
                                                          (quote
                                                            cljs.core/alength))
                                                        (clojure.core/list
                                                          (clojure.core/seq
                                                            (clojure.core/concat
                                                              (clojure.core/list
                                                                (quote
                                                                  cljs.core/js-arguments))))))))))))))))))))))))))))
          (map (fn* [p1__7895#] (fn-method name p1__7895#)) fdecl)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote set!))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote .))
                      (clojure.core/list name)
                      (clojure.core/list
                        (quote -cljs$lang$maxFixedArity)))))
                (clojure.core/list maxfa))))
          (clojure.core/list
            (core/when
              emit-var?
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote var))
                  (clojure.core/list name))))))))))
(clojure.core/defn exists?
  "Return true if argument exists, analogous to usage of typeof operator\n   in JavaScript."
  ([&form &env x]
    (if (core/symbol? x)
      (core/let
        [x
         (core/cond->
           (:name (cljs.analyzer/resolve-var &env x))
           (= "js" (namespace x))
           name)
         segs
         (string/split
           (core/str (string/replace-first (core/str x) "/" "."))
           #"\.")
         n
         (count segs)
         syms
         (map
           (fn*
             [p1__6638#]
             (vary-meta
               (symbol "js" (string/join "." p1__6638#))
               assoc
               :cljs.analyzer/no-resolve
               true))
           (reverse (take n (iterate butlast segs))))
         js
         (string/join
           " && "
           (repeat n "(typeof ~{} !== 'undefined')"))]
        (bool-expr (concat (core/list (quote js*) js) syms)))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/some?))
          (clojure.core/list x))))))
(core/defn
  destructure
  [bindings]
  (core/let
    [bents
     (partition 2 bindings)
     pb
     (core/fn
       pb
       [bvec b v]
       (core/let
         [pvec
          (core/fn
            [bvec b val]
            (core/let
              [gvec
               (gensym "vec__")
               gseq
               (gensym "seq__")
               gfirst
               (gensym "first__")
               has-rest
               (some #{(quote &)} b)]
              (core/loop
                [ret
                 (core/let
                   [ret (conj bvec gvec val)]
                   (if has-rest
                     (conj
                       ret
                       gseq
                       (core/list (quote clojure.core/seq) gvec))
                     ret))
                 n
                 0
                 bs
                 b
                 seen-rest?
                 false]
                (if (seq bs)
                  (core/let
                    [firstb (first bs)]
                    (core/cond
                      (= firstb (quote &))
                      (recur
                        (pb ret (second bs) gseq)
                        n
                        (nnext bs)
                        true)
                      (= firstb :as)
                      (pb ret (second bs) gvec)
                      :else
                      (if seen-rest?
                        (throw
                          (new
                            Exception
                            "Unsupported binding form, only :as can follow & parameter"))
                        (recur
                          (pb
                            (if has-rest
                              (conj
                                ret
                                gfirst
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote clojure.core/first))
                                    (clojure.core/list gseq)))
                                gseq
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote clojure.core/next))
                                    (clojure.core/list gseq))))
                              ret)
                            firstb
                            (if has-rest
                              gfirst
                              (core/list
                                (quote clojure.core/nth)
                                gvec
                                n
                                nil)))
                          (core/inc n)
                          (next bs)
                          seen-rest?))))
                  ret))))
          pmap
          (core/fn
            [bvec b v]
            (core/let
              [gmap (gensym "map__") defaults (:or b)]
              (core/loop
                [ret
                 (core/->
                   bvec
                   (conj gmap)
                   (conj v)
                   (conj gmap)
                   (conj
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list
                           (quote cljs.core/--destructure-map))
                         (clojure.core/list gmap))))
                   ((core/fn
                      [ret]
                      (if (:as b) (conj ret (:as b) gmap) ret))))
                 bes
                 (core/let
                   [transforms
                    (reduce
                      (core/fn
                        [transforms mk]
                        (if (core/keyword? mk)
                          (core/let
                            [mkns (namespace mk) mkn (name mk)]
                            (core/cond
                              (= mkn "keys")
                              (assoc
                                transforms
                                mk
                                (fn*
                                  [p1__6436#]
                                  (keyword
                                    (core/or
                                      mkns
                                      (namespace p1__6436#))
                                    (name p1__6436#))))
                              (= mkn "syms")
                              (assoc
                                transforms
                                mk
                                (fn*
                                  [p1__6437#]
                                  (core/list
                                    (quote quote)
                                    (symbol
                                      (core/or
                                        mkns
                                        (namespace p1__6437#))
                                      (name p1__6437#)))))
                              (= mkn "strs")
                              (assoc transforms mk core/str)
                              :else
                              transforms))
                          transforms))
                      {}
                      (keys b))]
                   (reduce
                     (core/fn
                       [bes entry]
                       (reduce
                         (fn*
                           [p1__6438# p2__6439#]
                           (assoc
                             p1__6438#
                             p2__6439#
                             ((val entry) p2__6439#)))
                         (dissoc bes (key entry))
                         ((key entry) bes)))
                     (dissoc b :as :or)
                     transforms))]
                (if (seq bes)
                  (core/let
                    [bb
                     (key (first bes))
                     bk
                     (val (first bes))
                     local
                     (if (core/instance? clojure.lang.Named bb)
                       (with-meta (symbol nil (name bb)) (meta bb))
                       bb)
                     bv
                     (if (contains? defaults local)
                       (core/list
                         (quote cljs.core/get)
                         gmap
                         bk
                         (defaults local))
                       (core/list (quote cljs.core/get) gmap bk))]
                    (recur
                      (if (core/or
                            (core/keyword? bb)
                            (core/symbol? bb))
                        (core/-> ret (conj local bv))
                        (pb ret bb bv))
                      (next bes)))
                  ret))))]
         (core/cond
           (core/symbol? b)
           (core/->
             bvec
             (conj (if (namespace b) (symbol (name b)) b))
             (conj v))
           (core/keyword? b)
           (core/-> bvec (conj (symbol (name b))) (conj v))
           (vector? b)
           (pvec bvec b v)
           (map? b)
           (pmap bvec b v)
           :else
           (throw
             (new
               Exception
               (core/str "Unsupported binding form: " b))))))
     process-entry
     (core/fn [bvec b] (pb bvec (first b) (second b)))]
    (if (every? core/symbol? (map first bents))
      bindings
      (core/if-let
        [kwbs
         (seq
           (filter
             (fn* [p1__6440#] (core/keyword? (first p1__6440#)))
             bents))]
        (throw
          (new
            Exception
            (core/str "Unsupported binding key: " (ffirst kwbs))))
        (reduce process-entry [] bents)))))
(clojure.core/defn defprotocol
  "A protocol is a named set of named methods and their signatures:\n\n  (defprotocol AProtocolName\n    ;optional doc string\n    \"A doc string for AProtocol abstraction\"\n\n  ;method signatures\n    (bar [this a b] \"bar docs\")\n    (baz [this a] [this a b] [this a b c] \"baz docs\"))\n\n  No implementations are provided. Docs can be specified for the\n  protocol overall and for each method. The above yields a set of\n  polymorphic functions and a protocol object. All are\n  namespace-qualified by the ns enclosing the definition The resulting\n  functions dispatch on the type of their first argument, which is\n  required and corresponds to the implicit target object ('this' in\n  JavaScript parlance). defprotocol is dynamic, has no special compile-time\n  effect, and defines no new types.\n\n  (defprotocol P\n    (foo [this])\n    (bar-me [this] [this y]))\n\n  (deftype Foo [a b c]\n    P\n    (foo [this] a)\n    (bar-me [this] b)\n    (bar-me [this y] (+ c y)))\n\n  (bar-me (Foo. 1 2 3) 42)\n  => 45\n\n  (foo\n    (let [x 42]\n      (reify P\n        (foo [this] 17)\n        (bar-me [this] x)\n        (bar-me [this y] x))))\n  => 17"
  ([&form &env psym & doc+methods]
    (core/let
      [p
       (:name (cljs.analyzer/resolve-var (dissoc &env :locals) psym))
       [opts methods]
       (core/loop
         [opts {:protocol-symbol true} methods [] sigs doc+methods]
         (core/if-not
           (seq sigs)
           [opts methods]
           (core/let
             [[head & tail] sigs]
             (core/cond
               (core/string? head)
               (recur (assoc opts :doc head) methods tail)
               (core/keyword? head)
               (recur
                 (assoc opts head (first tail))
                 methods
                 (rest tail))
               (core/seq? head)
               (recur opts (conj methods head) tail)
               :else
               (throw
                 (Exception.
                   (core/str
                     "Invalid protocol, "
                     psym
                     " received unexpected argument")))))))
       psym
       (vary-meta psym merge opts)
       ns-name
       (core/-> &env :ns :name)
       fqn
       (core/fn [n] (symbol (core/str ns-name) (core/str n)))
       prefix
       (protocol-prefix p)
       _
       (core/doseq
         [[mname & arities] methods]
         (core/when
           (some #{0} (map count (filter vector? arities)))
           (throw
             (Exception.
               (core/str
                 "Invalid protocol, "
                 psym
                 " defines method "
                 mname
                 " with arity 0")))))
       sig->syms
       (core/fn
         [sig]
         (core/if-not
           (every? core/symbol? sig)
           (mapv
             (core/fn
               [arg]
               (core/cond
                 (core/symbol? arg)
                 arg
                 (core/and (map? arg) (core/some? (:as arg)))
                 (:as arg)
                 :else
                 (gensym)))
             sig)
           sig))
       expand-dyn
       (core/fn
         [fname sig]
         (core/let
           [sig
            (sig->syms sig)
            fqn-fname
            (with-meta (fqn fname) {:cljs.analyzer/no-resolvetrue})fsig           (first           sig)check(clojure.core/seq(clojure.core/concat(clojure.core/list          (quotecljs.core/let)
                )(clojure.core/list(clojure.core/applyclojure.core/vector (clojure.core/seq(
                  clojure.core/concat
                    (clojure.core/list(
                    quotem__7283__auto__                    ))(clojure.core/list
                        (clojure.core/seq( clojure.core/concat(clojure.core/list            (quotecljs.core/unchecked-get                ))(clojure.core/list                          fqn-fname)(clojure.core/list                       "_"))))))))(clojure.core/list                      (clojure.core/seq(clojure.core/concat                          (clojure.core/list (quotecljs.core/if-not                   ))(clojure.core/list(clojure.core/seq          (clojure.core/concat                 (clojure.core/list                    (quotecljs.core/nil?
                      ))(clojure.core/list(quotem__7283__auto__)))
                      ))(clojure.core/list                       (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote m__7283__auto__)
                            )sig)))(clojure.core/list                        (clojure.core/seq(clojure.core/concat             (clojure.core/list
                        (quotethrow))(clojure.core/list             (clojure.core/seq(clojure.core/concat            (clojure.core/list (quote cljs.core/missing-protocol                    ))(clojure.core/list         (core/strpsym"."fname                      ))(clojure.core/list                        fsig))))))))))))check                            (clojure.core/seq( clojure.core/concat                        (clojure.core/list
                              (quotecljs.core/let                               ))(clojure.core/list
                                  (clojure.core/apply                                    clojure.core/vector(clojure.core/seq                                  (clojure.core/concat                                   (clojure.core/list (quotex__7284__auto__                     ))(clojure.core/list(clojure.core/seq           (clojure.core/concat(clojure.core/list            (quoteif))(clojure.core/list         (clojure.core/seq( clojure.core/concat(clojure.core/list  (quotecljs.core/nil?                 ))(clojure.core/list                    fsig))))(clojure.core/list              (quotenil))(clojure.core/list           fsig))))(clojure.core/list                   (quotem__7285__auto__))(clojure.core/list(clojure.core/seq          (clojure.core/concat                         (clojure.core/list                            (quotecljs.core/unchecked-get                      ))(clojure.core/listfqn-fname)
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote goog/typeOf))(clojure.core/list                      (quotex__7284__auto__))))))
                              ))))))(clojure.core/list( clojure.core/seq                    (clojure.core/concat(clojure.core/list              (quotecljs.core/if-not))( clojure.core/list
                        (clojure.core/seq(
                          clojure.core/concat                           (clojure.core/list(quote                           cljs.core/nil?))(clojure.core/list                 (quote m__7285__auto__)))))(clojure.core/list                  (clojure.core/seq( clojure.core/concat                      (clojure.core/list
                                (quotem__7285__auto__                               ))sig)))(clojure.core/list                               check))))))](clojure.core/seq                            (clojure.core/concat
                                    (clojure.core/list
                                      sig)(clojure.core/list                         check)))))expand-sig(core/fn                [fnamedyn-nameslot
                  sig](core/let[sig
                    (sig->symssig)fqn-fname                    (with-meta(fqnfname){:cljs.analyzer/no-resolve                     true})fsig(firstsig                        )check(clojure.core/seq                     (clojure.core/concat
                            (clojure.core/list (quote if))(clojure.core/list                       (clojure.core/seq(
                              clojure.core/concat(clojure.core/list             (quotecljs.core/and                        ))(clojure.core/list                        (clojure.core/seq(clojure.core/concat            (clojure.core/list (quote clojure.core/not)
                            )(clojure.core/list          (clojure.core/seq( clojure.core/concat     (clojure.core/list             (quotecljs.core/nil?
               ))(clojure.core/listfsig               )))))))(clojure.core/list(clojure.core/seq(clojure.core/concat(
         clojure.core/list(quoteclojure.core/not))(clojure.core/list(
            clojure.core/seq            (clojure.core/concat  (clojure.core/list(quotecljs.core/nil?))(clojure.core/list            (clojure.core/seq(clojure.core/concat    (clojure.core/list(quote.))(clojure.core/list     fsig)(clojure.core/list              (with-meta(symbol( core/str"-"
                slot)){:protocol-prop                true}))))))))))))
                    ))(clojure.core/list
                      (clojure.core/seq( clojure.core/concat(clojure.core/list        (quote.))(clojure.core/list                fsig)(clojure.core/list                     slot)sig)))(clojure.core/list                    (clojure.core/seq(
                              clojure.core/concat(clojure.core/list                 dyn-name)sig)))))check                           (core/if-not(:extend-via-metadata                 opts)check(clojure.core/seq                            (clojure.core/concat                                   (clojure.core/list(quote                                  cljs.core/if-let)) (clojure.core/list                (clojure.core/apply                        clojure.core/vector                         (clojure.core/seq(clojure.core/concat            (clojure.core/list
                              (quote meta-impl__7286__auto__                        ))(clojure.core/list                             (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/->))(clojure.core/list                   fsig)(clojure.core/list                                (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list (quote clojure.core/meta                           )))))(clojure.core/list(
                                        clojure.core/seq(clojure.core/concat                         (clojure.core/list                                     (quoteclojure.core/get                                ))(clojure.core/list
                                            (clojure.core/seq                                            (clojure.core/concat                (clojure.core/list
                  (quotequote))(clojure.core/list       fqn-fname)))))))))))
                      )))(clojure.core/list(clojure.core/seq              (clojure.core/concat(clojure.core/list         (quotemeta-impl__7286__auto__                  ))sig)
                ))(clojure.core/list                 check))))](clojure.core/seq           (clojure.core/concat
                      (clojure.core/list sig)(clojure.core/list          check)))
            ))psym            (core/->psym
              (vary-metaupdate-in[:jsdoc]
              conj"@interface"    )(vary-metaassoc-in               [:protocol-info:methods                ](into{}(map(core/fn[[fname&sigs]](core/let[
                  doc(core/as->(last
                    sigs)doc(core/when(
                      core/string?doc)doc
                      ))sigs(take-while
                        vector?sigs)][(vary-meta                       fnameassoc:docdoc)
                            (vecsigs)]))methods)))(vary-meta
                          assoc-in[:sigs](into                           {}(map(core/fn[[fname                           &sigs]](core/let[doc
                                (core/as->(lastsigs                                  )doc(core/when(core/string?                           doc)doc))sigs(take-while
                                vector?sigs)][(keyword                               fname){:namefname
                                    :arglists(list*sigs)
                                      :docdoc}]))methods
                                        ))))method(core/fn[[fname&sigs                                ]](core/let[doc(core/as->                            (lastsigs)doc(core/when                               (core/string?doc)doc
                                      ))sigs(take-whilevector?                                   sigs)amp(core/when(some#{
                                      (quote&)}(applyconcat                                      sigs))(cljs.analyzer/warning                                :protocol-with-variadic-method                                   &env{:protocolpsym
                                              :namefname}))_
                                            (core/when-some[existing                                         (core/get(->&env:ns:defs                  )fname)](core/when-not                 (=p(:protocolexisting                   ))(cljs.analyzer/warning                     :protocol-with-overwriting-method            {}{:protocolpsym:namefname:existing                      existing                 })))slot(symbol(core/strprefix           (munge(namefname)
             )))dyn-name(symbol(core/str         slot"$dyn"))fname( vary-meta           fnameassoc:protocolp:docdoc)]
       (clojure.core/seq(clojure.core/concat       (clojure.core/list(quotecljs.core/let))(clojure.core/list (clojure.core/apply   clojure.core/vector (clojure.core/seq(clojure.core/concat(clojure.core/list dyn-name        )(clojure.core/list (clojure.core/seq         (clojure.core/concat              (clojure.core/list           (quote                   clojure.core/fn                  ))(map(core/fn                    [sig                      ](expand-dynfnamesig))sigs))) )))))
                    (clojure.core/list       (clojure.core/seq(clojure.core/concat         (clojure.core/list(quotecljs.core/defn ))(clojure.core/list    fname)(map
         (core/fn[sig          ](expand-sig        fnamedyn-name      (with-meta         (symbol         (core/str           slot"$arity$"             (countsig ))){:protocol-prop      true})sig
                   ))sigs                   ))))))))](
                      clojure.core/seq                  (clojure.core/concat      (clojure.core/list(quote do)) (clojure.core/list        (clojure.core/seq        (clojure.core/concat(clojure.core/list        (quoteset!))(clojure.core/list       (quote *unchecked-if*)) (clojure.core/list (quotetrue             )))))(clojure.core/list(clojure.core/seq(
         clojure.core/concat       (clojure.core/list   (quote           def))(clojure.core/list  psym) (clojure.core/list  (clojure.core/seq (clojure.core/concat(clojure.core/list          (quote           js*))(clojure.core/list"function(){}" )))
            ))))(mapmethod           methods)(clojure.core/list(clojure.core/seq           (clojure.core/concat(clojure.core/list (quoteset!))(clojure.core/list
                (quote               *unchecked-if*)  )(clojure.core/list        (
            quotefalse)))))
              )))))
(clojure.core/defn doseq
  "Repeatedly executes body (presumably for side-effects) with\n  bindings and filtering as provided by \"for\".  Does not retain\n  the head of the sequence. Returns nil."
  ([&form &env seq-exprs & body]
    (assert-args
      doseq
      (vector? seq-exprs)
      "a vector for its binding"
      (even? (count seq-exprs))
      "an even number of forms in binding vector")
    (core/let
      [err
       (core/fn [& msg] (throw (ex-info (apply core/str msg) {})))
       step
       (core/fn
         step
         [recform exprs]
         (core/if-not
           exprs
           [true
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote do))
                body
                (clojure.core/list (quote nil))))]
           (core/let
             [k
              (first exprs)
              v
              (second exprs)
              seqsym
              (gensym "seq__")
              recform
              (if (core/keyword? k)
                recform
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote recur))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote clojure.core/next))
                          (clojure.core/list seqsym))))
                    (clojure.core/list (quote nil))
                    (clojure.core/list 0)
                    (clojure.core/list 0))))
              steppair
              (step recform (nnext exprs))
              needrec
              (steppair 0)
              subform
              (steppair 1)]
             (core/cond
               (= k :let)
               [needrec
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list v)
                    (clojure.core/list subform)))]
               (= k :while)
               [false
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/when))
                    (clojure.core/list v)
                    (clojure.core/list subform)
                    (core/when needrec [recform])))]
               (= k :when)
               [false
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list v)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote do))
                          (clojure.core/list subform)
                          (core/when needrec [recform]))))
                    (clojure.core/list recform)))]
               (core/keyword? k)
               (err "Invalid 'doseq' keyword" k)
               :else
               (core/let
                 [chunksym
                  (with-meta
                    (gensym "chunk__")
                    {:tag (quote not-native)})
                  countsym
                  (gensym "count__")
                  isym
                  (gensym "i__")
                  recform-chunk
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote recur))
                      (clojure.core/list seqsym)
                      (clojure.core/list chunksym)
                      (clojure.core/list countsym)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/unchecked-inc))
                            (clojure.core/list isym))))))
                  steppair-chunk
                  (step recform-chunk (nnext exprs))
                  subform-chunk
                  (steppair-chunk 1)]
                 [true
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/loop))
                      (clojure.core/list
                        (clojure.core/apply
                          clojure.core/vector
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list seqsym)
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote clojure.core/seq))
                                    (clojure.core/list v))))
                              (clojure.core/list chunksym)
                              (clojure.core/list (quote nil))
                              (clojure.core/list countsym)
                              (clojure.core/list 0)
                              (clojure.core/list isym)
                              (clojure.core/list 0)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote if))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/coercive-boolean))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote cljs.core/<))
                                        (clojure.core/list isym)
                                        (clojure.core/list
                                          countsym)))))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/let))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/vector
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list k)
                                          (clojure.core/list
                                            (clojure.core/seq
                                              (clojure.core/concat
                                                (clojure.core/list
                                                  (quote
                                                    cljs.core/-nth))
                                                (clojure.core/list
                                                  chunksym)
                                                (clojure.core/list
                                                  isym))))))))
                                  (clojure.core/list subform-chunk)
                                  (core/when
                                    needrec
                                    [recform-chunk]))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.core/when-let))
                                  (clojure.core/list
                                    (clojure.core/apply
                                      clojure.core/vector
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list seqsym)
                                          (clojure.core/list
                                            (clojure.core/seq
                                              (clojure.core/concat
                                                (clojure.core/list
                                                  (quote
                                                    clojure.core/seq))
                                                (clojure.core/list
                                                  seqsym))))))))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list (quote if))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote
                                                  clojure.core/chunked-seq?))
                                              (clojure.core/list
                                                seqsym))))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote cljs.core/let))
                                              (clojure.core/list
                                                (clojure.core/apply
                                                  clojure.core/vector
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        (quote
                                                          c__7507__auto__))
                                                      (clojure.core/list
                                                        (clojure.core/seq
                                                          (clojure.core/concat
                                                            (clojure.core/list
                                                              (quote
                                                                clojure.core/chunk-first))
                                                            (clojure.core/list
                                                              seqsym))))))))
                                              (clojure.core/list
                                                (clojure.core/seq
                                                  (clojure.core/concat
                                                    (clojure.core/list
                                                      (quote recur))
                                                    (clojure.core/list
                                                      (clojure.core/seq
                                                        (clojure.core/concat
                                                          (clojure.core/list
                                                            (quote
                                                              clojure.core/chunk-rest))
                                                          (clojure.core/list
                                                            seqsym))))
                                                    (clojure.core/list
                                                      (quote
                                                        c__7507__auto__))
                                                    (clojure.core/list
                                                      (clojure.core/seq
                                                        (clojure.core/concat
                                                          (clojure.core/list
                                                            (quote
                                                              clojure.core/count))
                                                          (clojure.core/list
                                                            (quote
                                                              c__7507__auto__)))))
                                                    (clojure.core/list
                                                      0)))))))
                                        (clojure.core/list
                                          (clojure.core/seq
                                            (clojure.core/concat
                                              (clojure.core/list
                                                (quote cljs.core/let))
                                              (clojure.core/list
                                                (clojure.core/apply
                                                  clojure.core/vector
                                                  (clojure.core/seq
                                                    (clojure.core/concat
                                                      (clojure.core/list
                                                        k)
                                                      (clojure.core/list
                                                        (clojure.core/seq
                                                          (clojure.core/concat
                                                            (clojure.core/list
                                                              (quote
                                                                clojure.core/first))
                                                            (clojure.core/list
                                                              seqsym))))))))
                                              (clojure.core/list
                                                subform)
                                              (core/when
                                                needrec
                                                [recform])))))))))))))))])))))]
      (nth (step nil (seq seq-exprs)) 1))))
(core/defn-
  assert-valid-fdecl
  "A good fdecl looks like (([a] ...) ([a b] ...)) near the end of defn."
  [fdecl]
  (core/when
    (empty? fdecl)
    (throw
      (IllegalArgumentException. "Parameter declaration missing")))
  (core/let
    [argdecls
     (map
       (fn*
         [p1__6421#]
         (if (seq? p1__6421#)
           (first p1__6421#)
           (throw
             (IllegalArgumentException.
               (if (seq? (first fdecl))
                 (core/str
                   "Invalid signature \""
                   p1__6421#
                   "\" should be a list")
                 (core/str
                   "Parameter declaration \""
                   p1__6421#
                   "\" should be a vector"))))))
       fdecl)
     bad-args
     (seq (remove (fn* [p1__6422#] (vector? p1__6422#)) argdecls))]
    (core/when
      bad-args
      (throw
        (IllegalArgumentException.
          (core/str
            "Parameter declaration \""
            (first bad-args)
            "\" should be a vector"))))))
(core/defn-
  validate-impls
  [env impls]
  (core/loop
    [protos #{} impls impls]
    (core/when
      (seq impls)
      (core/let
        [proto
         (first impls)
         methods
         (take-while seq? (next impls))
         impls
         (drop-while seq? (next impls))]
        (core/when
          (contains? protos proto)
          (ana/warning :protocol-multiple-impls env {:protocol proto}))
        (core/loop
          [seen #{} methods methods]
          (core/when
            (seq methods)
            (core/let
              [[fname :as method] (first methods)]
              (core/when
                (contains? seen fname)
                (ana/warning
                  :extend-type-invalid-method-shape
                  env
                  {:protocol proto  :method fname}))
              (validate-impl-sigs env proto method)
              (recur (conj seen fname) (next methods)))))
        (recur (conj protos proto) impls)))))
(core/defn-
  resolve-var
  [env sym]
  (core/let
    [ret (:name (cljs.analyzer/resolve-var env sym))]
    (core/assert ret (core/str "Can't resolve: " sym))
    ret))
(clojure.core/defn goog-define
  "Defines a var using `goog.define`. Passed default value must be\n  string, number or boolean.\n\n  Default value can be overridden at compile time using the\n  compiler option `:closure-defines`.\n\n  Example:\n    (ns your-app.core)\n    (goog-define DEBUG! false)\n    ;; can be overridden with\n    :closure-defines {\"your_app.core.DEBUG_BANG_\" true}\n    or\n    :closure-defines {your-app.core/DEBUG! true}"
  ([&form &env sym default]
    (assert-args
      goog-define
      (core/or
        (core/string? default)
        (core/number? default)
        (core/true? default)
        (core/false? default))
      "a string, number or boolean as default value")
    (core/let
      [defname
       (comp/munge (core/str *ns* "/" sym))
       type
       (core/cond
         (core/string? default)
         "string"
         (core/number? default)
         "number"
         (core/or (core/true? default) (core/false? default))
         "boolean")]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list
            (if (:def-emits-var &env)
              (quote cljs.core/return-first)
              (quote do)))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/declare))
                (clojure.core/list
                  (core/vary-meta
                    sym
                    (core/fn
                      [m]
                      (core/cond->
                        m
                        (core/not (core/contains? m :tag))
                        (core/assoc :tag (core/symbol type)))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote def))
                (clojure.core/list
                  (vary-meta sym assoc :goog-define type))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote goog/define))
                      (clojure.core/list defname)
                      (clojure.core/list default))))))))))))
(clojure.core/defn js-obj
  ([&form &env & rest]
    (core/let
      [sym-or-str?
       (core/fn [x] (core/or (core/symbol? x) (core/string? x)))
       filter-on-keys
       (core/fn
         [f coll]
         (core/->> coll (filter (core/fn [[k _]] (f k))) (into {})))
       kvs
       (into {} (map vec (partition 2 rest)))
       sym-pairs
       (filter-on-keys core/symbol? kvs)
       expr->local
       (zipmap
         (filter (complement sym-or-str?) (keys kvs))
         (repeatedly gensym))
       obj
       (gensym "obj")]
      (if (empty? rest)
        (js-obj* (quote ()))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/let))
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (apply concat (clojure.set/map-invert expr->local))
                    (clojure.core/list obj)
                    (clojure.core/list
                      (js-obj* (filter-on-keys core/string? kvs)))))))
            (map
              (core/fn
                [[k v]]
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/unchecked-set))
                    (clojure.core/list obj)
                    (clojure.core/list k)
                    (clojure.core/list v))))
              sym-pairs)
            (map
              (core/fn
                [[k v]]
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/unchecked-set))
                    (clojure.core/list obj)
                    (clojure.core/list v)
                    (clojure.core/list (core/get kvs k)))))
              expr->local)
            (clojure.core/list obj)))))))
(core/defn-
  type-hint-sigs
  [type-sym sig]
  (if (vector? (second sig))
    (type-hint-single-arity-sig type-sym sig)
    (type-hint-multi-arity-sigs type-sym sig)))
(clojure.core/defn condp
  "Takes a binary predicate, an expression, and a set of clauses.\n  Each clause can take the form of either:\n\n  test-expr result-expr\n\n  test-expr :>> result-fn\n\n  Note :>> is an ordinary keyword.\n\n  For each clause, (pred test-expr expr) is evaluated. If it returns\n  logical true, the clause is a match. If a binary clause matches, the\n  result-expr is returned, if a ternary clause matches, its result-fn,\n  which must be a unary function, is called with the result of the\n  predicate as its argument, the result of that call being the return\n  value of condp. A single default expression can follow the clauses,\n  and its value will be returned if no clause matches. If no default\n  expression is provided and no clause matches, an Error is thrown."
  {:added "1.0"}
  ([&form &env pred expr & clauses]
    (core/let
      [gpred
       (gensym "pred__")
       gexpr
       (gensym "expr__")
       emit
       (core/fn
         emit
         [pred expr args]
         (core/let
           [[[a b c :as clause] more]
            (split-at (if (= :>> (second args)) 3 2) args)
            n
            (count clause)]
           (core/cond
             (= 0 n)
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote throw))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list (quote js/Error.))
                       (clojure.core/list
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list (quote cljs.core/str))
                             (clojure.core/list "No matching clause: ")
                             (clojure.core/list expr)))))))))
             (= 1 n)
             a
             (= 2 n)
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote if))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list pred)
                       (clojure.core/list a)
                       (clojure.core/list expr))))
                 (clojure.core/list b)
                 (clojure.core/list (emit pred expr more))))
             :else
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote cljs.core/if-let))
                 (clojure.core/list
                   (clojure.core/apply
                     clojure.core/vector
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list (quote p__7396__auto__))
                         (clojure.core/list
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list pred)
                               (clojure.core/list a)
                               (clojure.core/list expr))))))))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list c)
                       (clojure.core/list (quote p__7396__auto__)))))
                 (clojure.core/list (emit pred expr more)))))))
       gres
       (gensym "res__")]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list gpred)
                  (clojure.core/list pred)
                  (clojure.core/list gexpr)
                  (clojure.core/list expr)))))
          (clojure.core/list (emit gpred gexpr clauses)))))))
(clojure.core/defn for
  "List comprehension. Takes a vector of one or more\n   binding-form/collection-expr pairs, each followed by zero or more\n   modifiers, and yields a lazy sequence of evaluations of expr.\n   Collections are iterated in a nested fashion, rightmost fastest,\n   and nested coll-exprs can refer to bindings created in prior\n   binding-forms.  Supported modifiers are: :let [binding-form expr ...],\n   :while test, :when test.\n\n  (take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)]  [x y]))"
  ([&form &env seq-exprs body-expr]
    (assert-args
      for
      (vector? seq-exprs)
      "a vector for its binding"
      (even? (count seq-exprs))
      "an even number of forms in binding vector")
    (core/let
      [to-groups
       (core/fn
         [seq-exprs]
         (reduce
           (core/fn
             [groups [k v]]
             (if (core/keyword? k)
               (conj (pop groups) (conj (peek groups) [k v]))
               (conj groups [k v])))
           []
           (partition 2 seq-exprs)))
       err
       (core/fn [& msg] (throw (ex-info (apply core/str msg) {})))
       emit-bind
       (core/fn
         emit-bind
         [[[bind expr & mod-pairs] & [[_ next-expr] :as next-groups]]]
         (core/let
           [giter
            (gensym "iter__")
            gxs
            (gensym "s__")
            do-mod
            (core/fn
              do-mod
              [[[k v :as pair] & etc]]
              (core/cond
                (= k :let)
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list v)
                    (clojure.core/list (do-mod etc))))
                (= k :while)
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/when))
                    (clojure.core/list v)
                    (clojure.core/list (do-mod etc))))
                (= k :when)
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list v)
                    (clojure.core/list (do-mod etc))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote recur))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/rest))
                                (clojure.core/list gxs)))))))))
                (core/keyword? k)
                (err "Invalid 'for' keyword " k)
                next-groups
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote iterys__7454__auto__))
                            (clojure.core/list (emit-bind next-groups))
                            (clojure.core/list
                              (quote fs__7455__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/seq))
                                  (clojure.core/list
                                    (clojure.core/seq
                                      (clojure.core/concat
                                        (clojure.core/list
                                          (quote iterys__7454__auto__))
                                        (clojure.core/list
                                          next-expr)))))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote if))
                          (clojure.core/list (quote fs__7455__auto__))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/concat))
                                (clojure.core/list
                                  (quote fs__7455__auto__))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list giter)
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote
                                                clojure.core/rest))
                                            (clojure.core/list
                                              gxs))))))))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote recur))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote clojure.core/rest))
                                      (clojure.core/list
                                        gxs))))))))))))
                :else
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/cons))
                    (clojure.core/list body-expr)
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list giter)
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote clojure.core/rest))
                                (clojure.core/list gxs)))))))))))]
           (if next-groups
             (clojure.core/seq
               (clojure.core/concat
                 (clojure.core/list (quote cljs.core/fn))
                 (clojure.core/list giter)
                 (clojure.core/list
                   (clojure.core/apply
                     clojure.core/vector
                     (clojure.core/seq
                       (clojure.core/concat (clojure.core/list gxs)))))
                 (clojure.core/list
                   (clojure.core/seq
                     (clojure.core/concat
                       (clojure.core/list (quote cljs.core/lazy-seq))
                       (clojure.core/list
                         (clojure.core/seq
                           (clojure.core/concat
                             (clojure.core/list (quote cljs.core/loop))
                             (clojure.core/list
                               (clojure.core/apply
                                 clojure.core/vector
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list gxs)
                                     (clojure.core/list gxs)))))
                             (clojure.core/list
                               (clojure.core/seq
                                 (clojure.core/concat
                                   (clojure.core/list
                                     (quote cljs.core/when-first))
                                   (clojure.core/list
                                     (clojure.core/apply
                                       clojure.core/vector
                                       (clojure.core/seq
                                         (clojure.core/concat
                                           (clojure.core/list bind)
                                           (clojure.core/list gxs)))))
                                   (clojure.core/list
                                     (do-mod mod-pairs)))))))))))))
             (core/let
               [gi
                (gensym "i__")
                gb
                (gensym "b__")
                do-cmod
                (core/fn
                  do-cmod
                  [[[k v :as pair] & etc]]
                  (core/cond
                    (= k :let)
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/let))
                        (clojure.core/list v)
                        (clojure.core/list (do-cmod etc))))
                    (= k :while)
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/when))
                        (clojure.core/list v)
                        (clojure.core/list (do-cmod etc))))
                    (= k :when)
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote if))
                        (clojure.core/list v)
                        (clojure.core/list (do-cmod etc))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote recur))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/unchecked-inc))
                                    (clojure.core/list gi)))))))))
                    (core/keyword? k)
                    (err "Invalid 'for' keyword " k)
                    :else
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote do))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote clojure.core/chunk-append))
                              (clojure.core/list gb)
                              (clojure.core/list body-expr))))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote recur))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/unchecked-inc))
                                    (clojure.core/list gi)))))))))))]
               (clojure.core/seq
                 (clojure.core/concat
                   (clojure.core/list (quote cljs.core/fn))
                   (clojure.core/list giter)
                   (clojure.core/list
                     (clojure.core/apply
                       clojure.core/vector
                       (clojure.core/seq
                         (clojure.core/concat
                           (clojure.core/list gxs)))))
                   (clojure.core/list
                     (clojure.core/seq
                       (clojure.core/concat
                         (clojure.core/list (quote cljs.core/lazy-seq))
                         (clojure.core/list
                           (clojure.core/seq
                             (clojure.core/concat
                               (clojure.core/list
                                 (quote cljs.core/loop))
                               (clojure.core/list
                                 (clojure.core/apply
                                   clojure.core/vector
                                   (clojure.core/seq
                                     (clojure.core/concat
                                       (clojure.core/list gxs)
                                       (clojure.core/list gxs)))))
                               (clojure.core/list
                                 (clojure.core/seq
                                   (clojure.core/concat
                                     (clojure.core/list
                                       (quote cljs.core/when-let))
                                     (clojure.core/list
                                       (clojure.core/apply
                                         clojure.core/vector
                                         (clojure.core/seq
                                           (clojure.core/concat
                                             (clojure.core/list gxs)
                                             (clojure.core/list
                                               (clojure.core/seq
                                                 (clojure.core/concat
                                                   (clojure.core/list
                                                     (quote
                                                       clojure.core/seq))
                                                   (clojure.core/list
                                                     gxs))))))))
                                     (clojure.core/list
                                       (clojure.core/seq
                                         (clojure.core/concat
                                           (clojure.core/list
                                             (quote if))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote
                                                     clojure.core/chunked-seq?))
                                                 (clojure.core/list
                                                   gxs))))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote
                                                     cljs.core/let))
                                                 (clojure.core/list
                                                   (clojure.core/apply
                                                     clojure.core/vector
                                                     (clojure.core/seq
                                                       (clojure.core/concat
                                                         (clojure.core/list
                                                           (quote
                                                             c__7456__auto__))
                                                         (clojure.core/list
                                                           (clojure.core/with-meta
                                                             (clojure.core/seq
                                                               (clojure.core/concat
                                                                 (clojure.core/list
                                                                   (quote
                                                                     clojure.core/chunk-first))
                                                                 (clojure.core/list
                                                                   gxs)))
                                                             (clojure.core/apply
                                                               clojure.core/hash-map
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     :line)
                                                                   (clojure.core/list
                                                                     2509)
                                                                   (clojure.core/list
                                                                     :column)
                                                                   (clojure.core/list
                                                                     52)
                                                                   (clojure.core/list
                                                                     :tag)
                                                                   (clojure.core/list
                                                                     (quote
                                                                       cljs.core/not-native)))))))
                                                         (clojure.core/list
                                                           (quote
                                                             size__7457__auto__))
                                                         (clojure.core/list
                                                           (clojure.core/seq
                                                             (clojure.core/concat
                                                               (clojure.core/list
                                                                 (quote
                                                                   clojure.core/count))
                                                               (clojure.core/list
                                                                 (quote
                                                                   c__7456__auto__)))))
                                                         (clojure.core/list
                                                           gb)
                                                         (clojure.core/list
                                                           (clojure.core/seq
                                                             (clojure.core/concat
                                                               (clojure.core/list
                                                                 (quote
                                                                   clojure.core/chunk-buffer))
                                                               (clojure.core/list
                                                                 (quote
                                                                   size__7457__auto__)))))))))
                                                 (clojure.core/list
                                                   (clojure.core/seq
                                                     (clojure.core/concat
                                                       (clojure.core/list
                                                         (quote if))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 cljs.core/coercive-boolean))
                                                             (clojure.core/list
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     (quote
                                                                       cljs.core/loop))
                                                                   (clojure.core/list
                                                                     (clojure.core/apply
                                                                       clojure.core/vector
                                                                       (clojure.core/seq
                                                                         (clojure.core/concat
                                                                           (clojure.core/list
                                                                             gi)
                                                                           (clojure.core/list
                                                                             0)))))
                                                                   (clojure.core/list
                                                                     (clojure.core/seq
                                                                       (clojure.core/concat
                                                                         (clojure.core/list
                                                                           (quote
                                                                             if))
                                                                         (clojure.core/list
                                                                           (clojure.core/seq
                                                                             (clojure.core/concat
                                                                               (clojure.core/list
                                                                                 (quote
                                                                                   cljs.core/<))
                                                                               (clojure.core/list
                                                                                 gi)
                                                                               (clojure.core/list
                                                                                 (quote
                                                                                   size__7457__auto__)))))
                                                                         (clojure.core/list
                                                                           (clojure.core/seq
                                                                             (clojure.core/concat
                                                                               (clojure.core/list
                                                                                 (quote
                                                                                   cljs.core/let))
                                                                               (clojure.core/list
                                                                                 (clojure.core/apply
                                                                                   clojure.core/vector
                                                                                   (clojure.core/seq
                                                                                     (clojure.core/concat
                                                                                       (clojure.core/list
                                                                                         bind)
                                                                                       (clojure.core/list
                                                                                         (clojure.core/seq
                                                                                           (clojure.core/concat
                                                                                             (clojure.core/list
                                                                                               (quote
                                                                                                 cljs.core/-nth))
                                                                                             (clojure.core/list
                                                                                               (quote
                                                                                                 c__7456__auto__))
                                                                                             (clojure.core/list
                                                                                               gi))))))))
                                                                               (clojure.core/list
                                                                                 (do-cmod
                                                                                   mod-pairs)))))
                                                                         (clojure.core/list
                                                                           (quote
                                                                             true)))))))))))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 clojure.core/chunk-cons))
                                                             (clojure.core/list
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     (quote
                                                                       clojure.core/chunk))
                                                                   (clojure.core/list
                                                                     gb))))
                                                             (clojure.core/list
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     giter)
                                                                   (clojure.core/list
                                                                     (clojure.core/seq
                                                                       (clojure.core/concat
                                                                         (clojure.core/list
                                                                           (quote
                                                                             clojure.core/chunk-rest))
                                                                         (clojure.core/list
                                                                           gxs))))))))))
                                                       (clojure.core/list
                                                         (clojure.core/seq
                                                           (clojure.core/concat
                                                             (clojure.core/list
                                                               (quote
                                                                 clojure.core/chunk-cons))
                                                             (clojure.core/list
                                                               (clojure.core/seq
                                                                 (clojure.core/concat
                                                                   (clojure.core/list
                                                                     (quote
                                                                       clojure.core/chunk))
                                                                   (clojure.core/list
                                                                     gb))))
                                                             (clojure.core/list
                                                               (quote
                                                                 nil)))))))))))
                                           (clojure.core/list
                                             (clojure.core/seq
                                               (clojure.core/concat
                                                 (clojure.core/list
                                                   (quote
                                                     cljs.core/let))
                                                 (clojure.core/list
                                                   (clojure.core/apply
                                                     clojure.core/vector
                                                     (clojure.core/seq
                                                       (clojure.core/concat
                                                         (clojure.core/list
                                                           bind)
                                                         (clojure.core/list
                                                           (clojure.core/seq
                                                             (clojure.core/concat
                                                               (clojure.core/list
                                                                 (quote
                                                                   clojure.core/first))
                                                               (clojure.core/list
                                                                 gxs))))))))
                                                 (clojure.core/list
                                                   (do-mod
                                                     mod-pairs)))))))))))))))))))))))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote iter__7458__auto__))
                  (clojure.core/list
                    (emit-bind (to-groups seq-exprs)))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote iter__7458__auto__))
                (clojure.core/list (second seq-exprs))))))))))
(core/defn-
  validate-impl-sigs
  [env p method]
  (core/when-not
    (= p (quote Object))
    (core/let
      [var
       (ana/resolve-var (dissoc env :locals) p)
       minfo
       (core/-> var :protocol-info :methods)
       method-name
       (first method)
       ->name
       (comp symbol name)
       [fname sigs]
       (if (core/vector? (second method))
         [(->name method-name) [(second method)]]
         [(->name method-name) (map first (rest method))])
       decmeths
       (core/get minfo fname :cljs.core/not-found)]
      (core/when
        (= decmeths :cljs.core/not-found)
        (ana/warning
          :protocol-invalid-method
          env
          {:protocol p  :fname fname  :no-such-method true}))
      (core/when
        (namespace method-name)
        (core/let
          [method-var
           (ana/resolve-var
             (dissoc env :locals)
             method-name
             ana/confirm-var-exist-warning)]
          (core/when-not
            (= (:name var) (:protocol method-var))
            (ana/warning
              :protocol-invalid-method
              env
              {:protocol p 
               :fname method-name 
               :no-such-method true}))))
      (core/loop
        [sigs sigs seen #{}]
        (core/when
          (seq sigs)
          (core/let
            [sig (first sigs) c (count sig)]
            (core/when
              (contains? seen c)
              (ana/warning
                :protocol-duped-method
                env
                {:protocol p  :fname fname}))
            (core/when
              (some (quote #{&}) sig)
              (ana/warning
                :protocol-impl-with-variadic-method
                env
                {:protocol p  :name fname}))
            (core/when
              (core/and
                (not= decmeths :cljs.core/not-found)
                (not (some #{c} (map count decmeths))))
              (ana/warning
                :protocol-invalid-method
                env
                {:protocol p  :fname fname  :invalid-arity c}))
            (recur (next sigs) (conj seen c))))))))
(clojure.core/defn vector
  ([&form &env] (quote (.-EMPTY cljs.core/PersistentVector)))
  ([&form &env & xs]
    (core/let
      [cnt (count xs)]
      (if (core/< cnt 32)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/PersistentVector.))
            (clojure.core/list (quote nil))
            (clojure.core/list cnt)
            (clojure.core/list 5)
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote .-EMPTY-NODE))
                  (clojure.core/list
                    (quote cljs.core/PersistentVector)))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  xs)))
            (clojure.core/list (quote nil))))
        (vary-meta
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote .fromArray))
              (clojure.core/list (quote cljs.core/PersistentVector))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/array))
                    xs)))
              (clojure.core/list (quote true))))
          assoc
          :tag
          (quote cljs.core/PersistentVector))))))
(core/defn-
  update-protocol-var
  [p type env]
  (core/when-not
    (= (quote Object) p)
    (core/if-let
      [var (cljs.analyzer/resolve-existing-var (dissoc env :locals) p)]
      (do
        (core/when-not
          (:protocol-symbol var)
          (cljs.analyzer/warning
            :invalid-protocol-symbol
            env
            {:protocol p}))
        (core/when
          (core/and
            (:protocol-deprecated cljs.analyzer/*cljs-warnings*)
            (core/-> var :deprecated)
            (not (core/-> p meta :deprecation-nowarn)))
          (cljs.analyzer/warning
            :protocol-deprecated
            env
            {:protocol p}))
        (core/when
          (:protocol-symbol var)
          (swap!
            env/*compiler*
            update-in
            [:cljs.analyzer/namespaces]
            (core/fn
              [ns]
              (update-in
                ns
                [(:ns var) :defs (symbol (name p)) :impls]
                conj
                type)))))
      (core/when
        (:undeclared cljs.analyzer/*cljs-warnings*)
        (cljs.analyzer/warning
          :undeclared-protocol-symbol
          env
          {:protocol p})))))
(clojure.core/defn min
  ([&form &env x] x)
  ([&form &env x y]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote x__6900__auto__))
                (clojure.core/list x)
                (clojure.core/list (quote y__6901__auto__))
                (clojure.core/list y)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote js*))
              (clojure.core/list "((~{} < ~{}) ? ~{} : ~{})")
              (clojure.core/list (quote x__6900__auto__))
              (clojure.core/list (quote y__6901__auto__))
              (clojure.core/list (quote x__6900__auto__))
              (clojure.core/list (quote y__6901__auto__))))))))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/min))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/min))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn max
  ([&form &env x] x)
  ([&form &env x y]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote x__6893__auto__))
                (clojure.core/list x)
                (clojure.core/list (quote y__6894__auto__))
                (clojure.core/list y)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote js*))
              (clojure.core/list "((~{} > ~{}) ? ~{} : ~{})")
              (clojure.core/list (quote x__6893__auto__))
              (clojure.core/list (quote y__6894__auto__))
              (clojure.core/list (quote x__6893__auto__))
              (clojure.core/list (quote y__6894__auto__))))))))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/max))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/max))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(core/defn-
  validate-fields
  [case name fields]
  (core/when-not
    (vector? fields)
    (throw
      (AssertionError.
        (core/str case " " name ", no fields vector given.")))))
(clojure.core/defn implements?
  "EXPERIMENTAL"
  ([&form &env psym x]
    (core/let
      [p
       (:name (cljs.analyzer/resolve-var (dissoc &env :locals) psym))
       prefix
       (protocol-prefix p)
       xsym
       (bool-expr (gensym))
       [part bit]
       (fast-path-protocols p)
       msym
       (symbol
         (core/str "-cljs$lang$protocol_mask$partition" part "$"))]
      (core/if-not
        (core/symbol? x)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/let))
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list xsym)
                    (clojure.core/list x)))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote if))
                  (clojure.core/list xsym)
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote if))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote cljs.core/or))
                              (clojure.core/list
                                (if
                                  bit
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.core/unsafe-bit-and))
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote .))
                                            (clojure.core/list xsym)
                                            (clojure.core/list msym))))
                                      (clojure.core/list bit)))
                                  false))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/identical?))
                                    (clojure.core/list
                                      (quote
                                        cljs.core/PROTOCOL_SENTINEL))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list (quote .))
                                          (clojure.core/list xsym)
                                          (clojure.core/list
                                            (symbol
                                              (core/str
                                                "-"
                                                prefix))))))))))))
                        (clojure.core/list (quote true))
                        (clojure.core/list (quote false)))))
                  (clojure.core/list (quote false)))))))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/if-not))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/nil?))
                  (clojure.core/list x))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote if))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/or))
                        (clojure.core/list
                          (if bit
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/unsafe-bit-and))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list (quote .))
                                      (clojure.core/list x)
                                      (clojure.core/list msym))))
                                (clojure.core/list bit)))
                            false))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/identical?))
                              (clojure.core/list
                                (quote cljs.core/PROTOCOL_SENTINEL))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list (quote .))
                                    (clojure.core/list x)
                                    (clojure.core/list
                                      (symbol
                                        (core/str
                                          "-"
                                          prefix))))))))))))
                  (clojure.core/list (quote true))
                  (clojure.core/list (quote false)))))
            (clojure.core/list (quote false))))))))
(clojure.core/defn satisfies?
  "Returns true if x satisfies the protocol"
  ([&form &env psym x]
    (core/let
      [p
       (:name (cljs.analyzer/resolve-var (dissoc &env :locals) psym))
       prefix
       (protocol-prefix p)
       xsym
       (bool-expr (gensym))
       [part bit]
       (fast-path-protocols p)
       msym
       (symbol
         (core/str "-cljs$lang$protocol_mask$partition" part "$"))]
      (core/if-not
        (core/symbol? x)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/let))
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list xsym)
                    (clojure.core/list x)))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/if-not))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/nil?))
                        (clojure.core/list xsym))))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote if))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote cljs.core/or))
                              (clojure.core/list
                                (if
                                  bit
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.core/unsafe-bit-and))
                                      (clojure.core/list
                                        (clojure.core/seq
                                          (clojure.core/concat
                                            (clojure.core/list
                                              (quote .))
                                            (clojure.core/list xsym)
                                            (clojure.core/list msym))))
                                      (clojure.core/list bit)))
                                  false))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/identical?))
                                    (clojure.core/list
                                      (quote
                                        cljs.core/PROTOCOL_SENTINEL))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list (quote .))
                                          (clojure.core/list xsym)
                                          (clojure.core/list
                                            (with-meta
                                              (symbol
                                                (core/str "-" prefix))
                                              {:protocol-prop
                                               true})))))))))))
                        (clojure.core/list (quote true))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote if))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote cljs.core/coercive-not))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list (quote .))
                                          (clojure.core/list xsym)
                                          (clojure.core/list
                                            msym)))))))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote
                                        cljs.core/native-satisfies?))
                                    (clojure.core/list psym)
                                    (clojure.core/list xsym))))
                              (clojure.core/list (quote false))))))))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list
                          (quote cljs.core/native-satisfies?))
                        (clojure.core/list psym)
                        (clojure.core/list xsym)))))))))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/if-not))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/nil?))
                  (clojure.core/list x))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote if))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/or))
                        (clojure.core/list
                          (if bit
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/unsafe-bit-and))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list (quote .))
                                      (clojure.core/list x)
                                      (clojure.core/list msym))))
                                (clojure.core/list bit)))
                            false))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/identical?))
                              (clojure.core/list
                                (quote cljs.core/PROTOCOL_SENTINEL))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list (quote .))
                                    (clojure.core/list x)
                                    (clojure.core/list
                                      (with-meta
                                        (symbol (core/str "-" prefix))
                                        {:protocol-prop
                                         true})))))))))))
                  (clojure.core/list (quote true))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote if))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/coercive-not))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list (quote .))
                                    (clojure.core/list x)
                                    (clojure.core/list msym)))))))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/native-satisfies?))
                              (clojure.core/list psym)
                              (clojure.core/list x))))
                        (clojure.core/list (quote false))))))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote cljs.core/native-satisfies?))
                  (clojure.core/list psym)
                  (clojure.core/list x))))))))))
(core/defn-
  check-valid-options
  "Throws an exception if the given option map contains keys not listed\n  as valid, else returns nil."
  [options & valid-keys]
  (core/when
    (seq (apply disj (apply core/hash-set (keys options)) valid-keys))
    (throw
      (apply
        core/str
        "Only these options are valid: "
        (first valid-keys)
        (map
          (fn* [p1__7629#] (core/str ", " p1__7629#))
          (rest valid-keys))))))
(clojure.core/defn /
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core//))
        (clojure.core/list 1)
        (clojure.core/list x))))
  ([&form &env x y] (core/list (quote js*) "(~{} / ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core//))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core//))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn aget
  ([&form &env array idx]
    (core/case
      (ana/checked-arrays)
      :warn
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aget))
          (clojure.core/list array)
          (clojure.core/list idx)))
      :error
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aget'))
          (clojure.core/list array)
          (clojure.core/list idx)))
      (core/list (quote js*) "(~{}[~{}])" array idx)))
  ([&form &env array idx & idxs]
    (core/case
      (ana/checked-arrays)
      :warn
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aget))
          (clojure.core/list array)
          (clojure.core/list idx)
          idxs))
      :error
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aget'))
          (clojure.core/list array)
          (clojure.core/list idx)
          idxs))
      (core/let
        [astr (apply core/str (repeat (count idxs) "[~{}]"))]
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote js*))
            (clojure.core/list (core/str "(~{}[~{}]" astr ")"))
            (clojure.core/list array)
            (clojure.core/list idx)
            idxs))))))
(clojure.core/defn unsafe-bit-and
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} & ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/unsafe-bit-and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/unsafe-bit-and))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn instance?
  ([&form &env c x]
    (bool-expr
      (if (clojure.core/symbol? c)
        (core/list (quote js*) "(~{} instanceof ~{})" x c)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/let))
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote c__6657__auto__))
                    (clojure.core/list c)
                    (clojure.core/list (quote x__6658__auto__))
                    (clojure.core/list x)))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote js*))
                  (clojure.core/list "(~{} instanceof ~{})")
                  (clojure.core/list (quote x__6658__auto__))
                  (clojure.core/list (quote c__6657__auto__)))))))))))
(clojure.core/defn bit-or
  ([&form &env x y] (core/list (quote js*) "(~{} | ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/bit-or))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/bit-or))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn bit-and
  ([&form &env x y] (core/list (quote js*) "(~{} & ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/bit-and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/bit-and))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn bit-xor
  ([&form &env x y] (core/list (quote js*) "(~{} ^ ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/bit-xor))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/bit-xor))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn bit-and-not
  ([&form &env x y] (core/list (quote js*) "(~{} & ~~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/bit-and-not))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/bit-and-not))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn aset
  ([&form &env array idx val]
    (core/case
      (ana/checked-arrays)
      :warn
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aset))
          (clojure.core/list array)
          (clojure.core/list idx)
          (clojure.core/list val)))
      :error
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aset'))
          (clojure.core/list array)
          (clojure.core/list idx)
          (clojure.core/list val)))
      (core/list (quote js*) "(~{}[~{}] = ~{})" array idx val)))
  ([&form &env array idx idx2 & idxv]
    (core/case
      (ana/checked-arrays)
      :warn
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aset))
          (clojure.core/list array)
          (clojure.core/list idx)
          (clojure.core/list idx2)
          idxv))
      :error
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/checked-aset'))
          (clojure.core/list array)
          (clojure.core/list idx)
          (clojure.core/list idx2)
          idxv))
      (core/let
        [n
         (core/dec (count idxv))
         astr
         (apply core/str (repeat n "[~{}]"))]
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote js*))
            (clojure.core/list
              (core/str "(~{}[~{}][~{}]" astr " = ~{})"))
            (clojure.core/list array)
            (clojure.core/list idx)
            (clojure.core/list idx2)
            idxv))))))
(clojure.core/defn make-array
  ([&form &env size]
    (vary-meta
      (if (core/number? size)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote cljs.core/array))
            (take size (repeat nil))))
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote js/Array.))
            (clojure.core/list size))))
      assoc
      :tag
      (quote array)))
  ([&form &env type size]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/make-array))
        (clojure.core/list size))))
  ([&form &env type size & more-sizes]
    (vary-meta
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote dims__7522__auto__))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote cljs.core/list))
                        more-sizes)))
                  (clojure.core/list (quote dimarray__7523__auto__))
                  (clojure.core/list
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list
                          (quote cljs.core/make-array))
                        (clojure.core/list size))))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/dotimes))
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote i__7524__auto__))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/alength))
                              (clojure.core/list
                                (quote dimarray__7523__auto__)))))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/aset))
                      (clojure.core/list
                        (quote dimarray__7523__auto__))
                      (clojure.core/list (quote i__7524__auto__))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/apply))
                            (clojure.core/list
                              (quote cljs.core/make-array))
                            (clojure.core/list (quote nil))
                            (clojure.core/list
                              (quote dims__7522__auto__)))))))))))
          (clojure.core/list (quote dimarray__7523__auto__))))
      assoc
      :tag
      (quote array))))
(clojure.core/defn ==
  ([&form &env x] true)
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} === ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/==))
              (clojure.core/list x)
              (clojure.core/list y))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/==))
              (clojure.core/list y)
              more)))))))
(clojure.core/defn >=
  ([&form &env x] true)
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} >= ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/>=))
              (clojure.core/list x)
              (clojure.core/list y))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/>=))
              (clojure.core/list y)
              more)))))))
(clojure.core/defn >
  ([&form &env x] true)
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} > ~{})" x y)))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/and))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/>))
              (clojure.core/list x)
              (clojure.core/list y))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/>))
              (clojure.core/list y)
              more)))))))
(clojure.core/defn divide
  ([&form &env x]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core//))
        (clojure.core/list 1)
        (clojure.core/list x))))
  ([&form &env x y] (core/list (quote js*) "(~{} / ~{})" x y))
  ([&form &env x y & more]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core//))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core//))
              (clojure.core/list x)
              (clojure.core/list y))))
        more))))
(clojure.core/defn coercive-not=
  ([&form &env x y]
    (bool-expr (core/list (quote js*) "(~{} != ~{})" x y))))
(clojure.core/defn unsafe-cast
  "EXPERIMENTAL: Subject to change. Unsafely cast a value to a different type."
  ([&form &env t x]
    (core/let
      [cast-expr (core/str "~{} = /** @type {" t "} */ (~{})")]
      (core/list (quote js*) cast-expr x x))))
(core/defn-
  do-rfn
  [f1 k fkv]
  (clojure.core/seq
    (clojure.core/concat
      (clojure.core/list (quote cljs.core/fn))
      (clojure.core/list
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list
              (clojure.core/apply
                clojure.core/vector
                (clojure.core/seq (clojure.core/concat))))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat (clojure.core/list f1)))))))
      (clojure.core/list
        (clojure.walk/postwalk
          (fn*
            [p1__7010#]
            (if (sequential? p1__7010#)
              ((if (vector? p1__7010#) vec identity)
                (core/remove #{k} p1__7010#))
              p1__7010#))
          fkv))
      (clojure.core/list fkv))))
(clojure.core/defn time
  "Evaluates expr and prints the time it took. Returns the value of expr."
  ([&form &env expr]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote start__7648__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.core/system-time)))))
                (clojure.core/list (quote ret__7649__auto__))
                (clojure.core/list expr)))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/prn))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/str))
                    (clojure.core/list "Elapsed time: ")
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote .toFixed))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote cljs.core/-))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote
                                          cljs.core/system-time)))))
                                (clojure.core/list
                                  (quote start__7648__auto__)))))
                          (clojure.core/list 6))))
                    (clojure.core/list " msecs")))))))
        (clojure.core/list (quote ret__7649__auto__))))))
(clojure.core/defn js-debugger
  "Emit JavaScript \"debugger;\" statement"
  ([&form &env]
    (core/list (quote do) (core/list (quote js*) "debugger") nil)))
(clojure.core/defn with-out-str
  "Evaluates exprs in a context in which *print-fn* is bound to .append\n  on a fresh StringBuffer.  Returns the string created by any nested\n  printing calls."
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote sb__7705__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote goog.string/StringBuffer.)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.core/*print-newline*))
                      (clojure.core/list (quote true))
                      (clojure.core/list (quote cljs.core/*print-fn*))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/fn))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote x__7706__auto__))))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote .append))
                                  (clojure.core/list
                                    (quote sb__7705__auto__))
                                  (clojure.core/list
                                    (quote x__7706__auto__))))))))))))
              body)))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/str))
              (clojure.core/list (quote sb__7705__auto__)))))))))
(clojure.core/defn return-first
  ([&form &env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote ret__6468__auto__))
                (clojure.core/list (first body))))))
        (rest body)
        (clojure.core/list (quote ret__6468__auto__))))))
(clojure.core/defn float ([&form &env x] x))
(clojure.core/defn memfn
  "Expands into code that creates a fn that expects to be passed an\n  object and any args and calls the named instance method on the\n  object passing the args. Use when you want to treat a JavaScript\n  method as a first-class fn."
  ([&form &env name & args]
    (core/let
      [t (with-meta (gensym "target") (meta name))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/fn))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat (clojure.core/list t) args))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote .))
                (clojure.core/list t)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list name)
                      args)))))))))))
(clojure.core/defn ns-special-form ([&form &env]))
(clojure.core/defn unchecked-char ([&form &env x] x))
(clojure.core/defn ns-unmap
  "Removes the mappings for the symbol from the namespace."
  ([&form &env quoted-ns quoted-sym]
    (core/assert
      (core/and
        (seq? quoted-ns)
        (= (first quoted-ns) (quote quote))
        (core/symbol? (second quoted-ns))
        (seq? quoted-sym)
        (= (first quoted-sym) (quote quote))
        (core/symbol? (second quoted-sym)))
      "Arguments to ns-unmap must be quoted symbols")
    (core/let
      [ns (second quoted-ns) sym (second quoted-sym)]
      (swap!
        env/*compiler*
        update-in
        [:cljs.analyzer/namespaces ns :defs]
        dissoc
        sym)
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/js-delete))
          (clojure.core/list (comp/munge ns))
          (clojure.core/list (comp/munge (core/str sym))))))))
(clojure.core/defn short ([&form &env x] x))
(clojure.core/defn unchecked-float ([&form &env x] x))
(clojure.core/defn unchecked-byte ([&form &env x] x))
(clojure.core/defn locking
  ([&form &env x & forms]
    (clojure.core/seq
      (clojure.core/concat (clojure.core/list (quote do)) forms))))
(clojure.core/defn macroexpand
  "Repeatedly calls macroexpand-1 on form until it no longer\n  represents a macro form, then returns it.  Note neither\n  macroexpand-1 nor macroexpand expand macros in subforms."
  ([&form &env quoted]
    (core/assert
      (core/= (core/first quoted) (quote quote))
      "Argument to macroexpand must be quoted")
    (core/let
      [form (second quoted) env &env]
      (if (seq? form)
        (core/loop
          [form form form' (ana/macroexpand-1 env form)]
          (core/if-not
            (core/identical? form form')
            (recur form' (ana/macroexpand-1 env form'))
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote quote))
                (clojure.core/list form')))))
        form))))
(core/defn-
  do-curried
  [name doc meta args body]
  (core/let
    [cargs (vec (butlast args))]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/defn))
        (clojure.core/list name)
        (clojure.core/list doc)
        (clojure.core/list meta)
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list cargs)
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.core/fn))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote x__7003__auto__))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list name)
                          cargs
                          (clojure.core/list
                            (quote x__7003__auto__)))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat (clojure.core/list args) body)))))))
(core/defn
  defmacro
  "Like defn, but the resulting function name is declared as a\n  macro and will be used as a macro by the compiler when it is\n  called."
  {:arglists
   (quote
     ([name doc-string? attr-map? [params*] body]
       [name doc-string? attr-map? ([params*] body) + attr-map?])) 
   :macro true}
  [&form &env name & args]
  (core/let
    [prefix
     (core/loop
       [p (core/list (vary-meta name assoc :macro true)) args args]
       (core/let
         [f (first args)]
         (if (core/string? f)
           (recur (cons f p) (next args))
           (if (map? f) (recur (cons f p) (next args)) p))))
     fdecl
     (core/loop
       [fd args]
       (if (core/string? (first fd))
         (recur (next fd))
         (if (map? (first fd)) (recur (next fd)) fd)))
     fdecl
     (if (vector? (first fdecl)) (core/list fdecl) fdecl)
     add-implicit-args
     (core/fn
       [fd]
       (core/let
         [args (first fd)]
         (cons
           (vec (cons (quote &form) (cons (quote &env) args)))
           (next fd))))
     add-args
     (core/fn
       [acc ds]
       (if (core/nil? ds)
         acc
         (core/let
           [d (first ds)]
           (if (map? d)
             (conj acc d)
             (recur (conj acc (add-implicit-args d)) (next ds))))))
     fdecl
     (seq (add-args [] fdecl))
     decl
     (core/loop
       [p prefix d fdecl]
       (if p (recur (next p) (cons (first p) d)) d))]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote ret__7925__auto__))
                (clojure.core/list
                  (cons (quote cljs.core/defn) decl))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote set!))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote .))
                    (clojure.core/list name)
                    (clojure.core/list (quote -cljs$lang$macro)))))
              (clojure.core/list (quote true)))))
        (clojure.core/list (quote ret__7925__auto__))))))
(clojure.core/defn defcurried
  "Builds another arity of the fn that returns a fn awaiting the last\n  param"
  ([&form &env name doc meta args & body]
    (do-curried name doc meta args body)))
(clojure.core/defn specify
  "Identical to specify! but does not mutate its first argument. The first\n  argument must be an ICloneable instance."
  ([&form &env expr & impls]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/specify!))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/clone))
              (clojure.core/list expr))))
        impls))))
(clojure.core/defn js-in
  ([&form &env key obj] (core/list (quote js*) "~{} in ~{}" key obj)))
(core/defn-
  simple-test-expr?
  [env ast]
  (core/and
    (#{:js
       :host-field
       :const
       :var
       :quote
       :invoke
       :js-var
       :host-call
       :local}
      (:op ast))
    ((quote #{seq boolean}) (cljs.analyzer/infer-tag env ast))))
(clojure.core/defn double ([&form &env x] x))
(clojure.core/defn ns-imports
  "Returns a map of the import mappings for the namespace."
  ([&form &env quoted-ns]
    (core/assert
      (core/and
        (seq? quoted-ns)
        (= (first quoted-ns) (quote quote))
        (core/symbol? (second quoted-ns)))
      "Argument to ns-imports must be a quoted symbol")
    (core/let
      [ns (second quoted-ns)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/into))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/hash-map
              (clojure.core/seq (clojure.core/concat))))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (map
                    (core/fn
                      [[ctor qualified-ctor]]
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/symbol))
                                  (clojure.core/list (name ctor)))))
                            (clojure.core/list
                              (symbol qualified-ctor))))))
                    (get-in
                      (clojure.core/deref env/*compiler*)
                      [:cljs.analyzer/namespaces ns :imports])))))))))))
(core/defn-
  type-hint-multi-arity-sig
  [type-sym sig]
  (list* (type-hint-first-arg type-sym (first sig)) (next sig)))
(clojure.core/defn lazy-cat
  "Expands to code which yields a lazy sequence of the concatenation\n  of the supplied colls.  Each coll expr is not evaluated until it is\n  needed.\n\n  (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))"
  ([&form &env & colls]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/concat))
        (map
          (fn*
            [p1__7712#]
            (core/list (quote cljs.core/lazy-seq) p1__7712#))
          colls)))))
(clojure.core/defn ns-publics
  "Returns a map of the public intern mappings for the namespace."
  ([&form &env quoted-ns]
    (core/assert
      (core/and
        (seq? quoted-ns)
        (= (first quoted-ns) (quote quote))
        (core/symbol? (second quoted-ns)))
      "Argument to ns-publics must be a quoted symbol")
    (core/let
      [ns (second quoted-ns)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/into))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/hash-map
              (clojure.core/seq (clojure.core/concat))))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (map
                    (core/fn
                      [[sym _]]
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/symbol))
                                  (clojure.core/list (name sym)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote var))
                                  (clojure.core/list
                                    (symbol
                                      (name ns)
                                      (name sym))))))))))
                    (filter
                      (core/fn
                        [[_ info]]
                        (not (core/-> info :meta :private)))
                      (get-in
                        (clojure.core/deref env/*compiler*)
                        [:cljs.analyzer/namespaces ns :defs]))))))))))))
(clojure.core/defn rfn
  "Builds 3-arity reducing fn given names of wrapped fn and key, and k/v impl."
  ([&form &env [f1 k] fkv] (do-rfn f1 k fkv)))
(clojure.core/defn hash-set
  ([&form &env]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote .-EMPTY))
        (clojure.core/list (quote cljs.core/PersistentHashSet)))))
  ([&form &env & xs]
    (if (core/and
          (core/<= (count xs) 8)
          (every?
            (fn*
              [p1__7562#]
              (= (:op (cljs.analyzer/unwrap-quote p1__7562#)) :const))
            (map
              (fn*
                [p1__7563#]
                (cljs.analyzer/no-warn
                  (cljs.analyzer/analyze &env p1__7563#)))
              xs))
          (= (count (into #{} xs)) (count xs)))
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/PersistentHashSet.))
          (clojure.core/list (quote nil))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list
                  (quote cljs.core/PersistentArrayMap.))
                (clojure.core/list (quote nil))
                (clojure.core/list (count xs))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/array))
                      (interleave xs (repeat nil)))))
                (clojure.core/list (quote nil)))))
          (clojure.core/list (quote nil))))
      (vary-meta
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote .createAsIfByAssoc))
            (clojure.core/list (quote cljs.core/PersistentHashSet))
            (clojure.core/list
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list (quote cljs.core/array))
                  xs)))))
        assoc
        :tag
        (quote cljs.core/PersistentHashSet)))))
(clojure.core/defn unchecked-double ([&form &env x] x))
(clojure.core/defn macroexpand-1
  "If form represents a macro form, returns its expansion,\n  else returns form."
  ([&form &env quoted]
    (core/assert
      (core/= (core/first quoted) (quote quote))
      "Argument to macroexpand-1 must be quoted")
    (core/let
      [form (second quoted)]
      (if (seq? form)
        (clojure.core/seq
          (clojure.core/concat
            (clojure.core/list (quote quote))
            (clojure.core/list (ana/macroexpand-1 &env form))))
        form))))
(clojure.core/defn ns-interns
  "Returns a map of the intern mappings for the namespace."
  ([&form &env quoted-ns]
    (core/assert
      (core/and
        (seq? quoted-ns)
        (= (first quoted-ns) (quote quote))
        (core/symbol? (second quoted-ns)))
      "Argument to ns-interns must be a quoted symbol")
    (core/let
      [ns (second quoted-ns)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/into))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/hash-map
              (clojure.core/seq (clojure.core/concat))))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (map
                    (core/fn
                      [[sym _]]
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote clojure.core/symbol))
                                  (clojure.core/list (name sym)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list (quote var))
                                  (clojure.core/list
                                    (symbol
                                      (name ns)
                                      (name sym))))))))))
                    (get-in
                      (clojure.core/deref env/*compiler*)
                      [:cljs.analyzer/namespaces ns :defs])))))))))))
(clojure.core/defn unchecked-short ([&form &env x] x))
(core/defn-
  elide-implicit-macro-args
  [arglists]
  (core/map
    (core/fn
      [arglist]
      (if (core/vector? arglist)
        (core/subvec arglist 2)
        (core/drop 2 arglist)))
    arglists))
(core/defn-
  type-hint-multi-arity-sigs
  [type-sym sigs]
  (list*
    (first sigs)
    (map (partial type-hint-multi-arity-sig type-sym) (rest sigs))))
(clojure.core/defn amap
  "Maps an expression across an array a, using an index named idx, and\n  return value named ret, initialized to a clone of a, then setting\n  each element of ret to the evaluation of expr, returning the new\n  array ret."
  ([&form &env a idx ret expr]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote a__7609__auto__))
                (clojure.core/list a)
                (clojure.core/list (quote l__7610__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/alength))
                      (clojure.core/list (quote a__7609__auto__)))))
                (clojure.core/list ret)
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/aclone))
                      (clojure.core/list
                        (quote a__7609__auto__)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/loop))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list idx)
                      (clojure.core/list 0)))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote if))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote cljs.core/<))
                          (clojure.core/list idx)
                          (clojure.core/list
                            (quote l__7610__auto__)))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list (quote do))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list
                                  (quote cljs.core/aset))
                                (clojure.core/list ret)
                                (clojure.core/list idx)
                                (clojure.core/list expr))))
                          (clojure.core/list
                            (clojure.core/seq
                              (clojure.core/concat
                                (clojure.core/list (quote recur))
                                (clojure.core/list
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote cljs.core/inc))
                                      (clojure.core/list idx))))))))))
                    (clojure.core/list ret)))))))))))
(clojure.core/defn simple-benchmark
  "Runs expr iterations times in the context of a let expression with\n  the given bindings, then prints out the bindings and the expr\n  followed by number of iterations and total time. The optional\n  argument print-fn, defaulting to println, sets function used to\n  print the result. expr's string representation will be produced\n  using pr-str in any case."
  ([&form
    &env
    bindings
    expr
    iterations
    &
    {:keys [print-fn]  :or {print-fn (quote println)}}]
    (core/let
      [bs-str (pr-str bindings) expr-str (pr-str expr)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote cljs.core/let))
          (clojure.core/list bindings)
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.core/let))
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote start__7655__auto__))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote .getTime))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote js/Date.))))))))
                        (clojure.core/list (quote ret__7656__auto__))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list
                                (quote cljs.core/dotimes))
                              (clojure.core/list
                                (clojure.core/apply
                                  clojure.core/vector
                                  (clojure.core/seq
                                    (clojure.core/concat
                                      (clojure.core/list
                                        (quote ___7657__auto__))
                                      (clojure.core/list
                                        iterations)))))
                              (clojure.core/list expr))))
                        (clojure.core/list (quote end__7658__auto__))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote .getTime))
                              (clojure.core/list
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote js/Date.))))))))
                        (clojure.core/list
                          (quote elapsed__7659__auto__))
                        (clojure.core/list
                          (clojure.core/seq
                            (clojure.core/concat
                              (clojure.core/list (quote cljs.core/-))
                              (clojure.core/list
                                (quote end__7658__auto__))
                              (clojure.core/list
                                (quote start__7655__auto__)))))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list print-fn)
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote cljs.core/str))
                            (clojure.core/list bs-str)
                            (clojure.core/list ", ")
                            (clojure.core/list expr-str)
                            (clojure.core/list ", ")
                            (clojure.core/list iterations)
                            (clojure.core/list " runs, ")
                            (clojure.core/list
                              (quote elapsed__7659__auto__))
                            (clojure.core/list " msecs")))))))))))))))
(clojure.core/defn byte ([&form &env x] x))
(clojure.core/defn js-comment
  "Emit a top-level JavaScript multi-line comment. New lines will create a\n  new comment line. Comment block will be preceded and followed by a newline"
  ([&form &env comment]
    (core/let
      [[x & ys] (string/split comment #"\n")]
      (core/list
        (quote js*)
        (core/str
          "\n/**\n"
          (core/str " * " x "\n")
          (core/->>
            ys
            (map
              (fn*
                [p1__6597#]
                (core/str
                  " * "
                  (string/replace p1__6597# #"^   " "")
                  "\n")))
            (reduce core/str ""))
          " */\n")))))
(clojure.core/defn js-str
  ([&form &env s] (core/list (quote js*) "''+~{}" s)))
cljs.analyzer.api 124/296 (41.9%)
(defn empty-env
  "Creates an empty analysis environment."
  []
  (ana/empty-env))
(clojure.core/defn no-warn
  "Disable analyzer warnings for any analysis executed in body."
  ([&form &env & body]
    (let [no-warnings (zipmap
                        (keys ana/*cljs-warnings*)
                        (repeat false))]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/binding))
          (clojure.core/list
            (clojure.core/apply
              clojure.core/vector
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote cljs.analyzer/*cljs-warnings*))
                  (clojure.core/list no-warnings)))))
          body)))))
(defn ns-resolve
  "Given a namespace and a symbol return the corresponding var analysis map.\n  Analagous to clojure.core/ns-resolve but returns var analysis map not Var."
  ([ns sym] (ns-resolve env/*compiler* ns sym))
  ([state ns sym]
    {:pre [(symbol? ns) (symbol? sym)]}
    (get-in
      (clojure.core/deref state)
      [:cljs.analyzer/namespaces ns :defs sym])))
(defn current-state
  "Return the current compiler state atom."
  []
  env/*compiler*)
(defn find-ns
  "Given a namespace return the corresponding namespace analysis map. Analagous\n  to clojure.core/find-ns."
  ([sym] (find-ns env/*compiler* sym))
  ([state sym]
    {:pre [(symbol? sym)]}
    (get-in
      (clojure.core/deref state)
      [:cljs.analyzer/namespaces sym])))
(defn ns-interns
  "Given a namespace return all the var analysis maps. Analagous to\n  clojure.core/ns-interns but returns var analysis maps not vars."
  ([ns] (ns-interns env/*compiler* ns))
  ([state ns]
    {:pre [(symbol? ns)]}
    (merge
      (get-in
        (clojure.core/deref state)
        [:cljs.analyzer/namespaces ns :macros])
      (get-in
        (clojure.core/deref state)
        [:cljs.analyzer/namespaces ns :defs]))))
(defn warning-enabled?
  "Test if the given warning-type is enabled."
  [warning-type]
  (ana/*cljs-warnings* warning-type))
(clojure.core/defn with-state
  "Run the body with the given compilation state Atom."
  ([&form &env state & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.env/with-compiler-env))
        (clojure.core/list state)
        body))))
(defn get-options
  "Return the compiler options from compiler state."
  ([] (get-options (current-state)))
  ([state] (get (clojure.core/deref state) :options)))
(defn get-js-index
  "Return the currently computed Google Closure js dependency index from the\n  compiler state."
  ([] (get-js-index (current-state)))
  ([state] (get (clojure.core/deref state) :js-dependency-index)))
(defn analyze
  "Given an environment, a map containing {:locals (mapping of names to bindings), :context\n     (one of :statement, :expr, :return), :ns (a symbol naming the\n     compilation ns)}, and form, returns an expression object (a map\n     containing at least :form, :op and :env keys). If expr has any (immediately)\n     nested exprs, must have :children entry. This must be a vector of keywords naming\n     the immediately nested fields mapped to an expr or vector of exprs. This will\n     facilitate code walking without knowing the details of the op set."
  ([env form] (analyze env form nil))
  ([env form name] (analyze env form name nil))
  ([env form name opts]
    (analyze
      (or (current-state) (empty-state opts))
      env
      form
      name
      opts))
  ([state env form name opts]
    (env/with-compiler-env
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (ana/analyze env form name opts)))))
(defn resolve
  "Given an analysis environment resolve a var. Analogous to\n   clojure.core/resolve"
  [env sym]
  {:pre [(map? env) (symbol? sym)]}
  (try
    (binding [ana/*private-var-access-nowarn* true]
      (ana/resolve-var env sym (ana/confirm-var-exists-throw)))
    (catch Exception e (ana/resolve-macro-var env sym))))
(defn empty-state
  "Creates an empty compilation state Atom. The optional opts arg is a map\n   representing the compiler configuration. See the documentation\n   for details: https://clojurescript.org/reference/compiler-options"
  ([]
    (if-not (nil? env/*compiler*)
      env/*compiler*
      (env/default-compiler-env)))
  ([opts] (env/default-compiler-env opts)))
(defn enabled-warnings
  "Get the enabled warning types."
  []
  ana/*cljs-warnings*)
(defn forms-seq
  "Seq of Clojure/ClojureScript forms from rdr, a java.io.Reader. Optionally\n     accepts a filename argument which will be used in any emitted errors."
  ([rdr] (ana/forms-seq* rdr nil))
  ([rdr filename] (ana/forms-seq* rdr filename)))
(defn ns-publics
  "Given a namespace return all the public var analysis maps. Analagous to\n  clojure.core/ns-publics but returns var analysis maps not vars."
  ([ns] (ns-publics env/*compiler* ns))
  ([state ns]
    {:pre [(symbol? ns)]}
    (->>
      (merge
        (get-in
          (clojure.core/deref state)
          [:cljs.analyzer/namespaces ns :macros])
        (get-in
          (clojure.core/deref state)
          [:cljs.analyzer/namespaces ns :defs]))
      (remove (fn [[k v]] (:private v)))
      (into {}))))
(defn remove-ns
  "Removes the namespace named by the symbol."
  ([ns] (remove-ns env/*compiler* ns))
  ([state ns]
    {:pre [(symbol? ns)]}
    (swap! state update-in [:cljs.analyzer/namespaces] dissoc ns)))
(clojure.core/defn with-passes
  "Evaluate the body with the provided sequence of compiler passes."
  ([&form &env passes & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.analyzer/*passes*))
                (clojure.core/list passes)))))
        body))))
(defn parse-ns
  "Helper for parsing only the essential namespace information from a\n      ClojureScript source file and returning a cljs.closure/IJavaScript compatible\n      map _not_ a namespace AST node.\n\n      By default does not load macros or perform any analysis of dependencies. If\n      opts parameter provided :analyze-deps and :load-macros keys their values will\n      be used for *analyze-deps* and *load-macros* bindings respectively. This\n      function does _not_ side-effect the ambient compilation environment unless\n      requested via opts where :restore is false."
  ([src] (parse-ns src nil nil))
  ([src opts] (parse-ns src nil opts))
  ([src dest opts]
    (parse-ns (or (current-state) (empty-state opts)) src dest opts))
  ([state src dest opts]
    (env/with-compiler-env
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (ana/parse-ns src dest opts)))))
(defn analyze-file
  "Given a java.io.File, java.net.URL or a string identifying a resource on the\n      classpath attempt to analyze it.\n\n      This function side-effects the ambient compilation environment\n      `cljs.env/*compiler*` to aggregate analysis information. opts argument is\n      compiler options, if :cache-analysis true will cache analysis to\n      \":output-dir/some/ns/foo.cljs.cache.edn\". This function does not return a\n      meaningful value."
  ([f] (analyze-file f nil))
  ([f opts]
    (analyze-file (or (current-state) (empty-state opts)) f opts))
  ([state f opts]
    (env/with-compiler-env
      state
      (binding [ana/*cljs-warning-handlers* (:warning-handlers
                                              opts
                                              ana/*cljs-warning-handlers*)]
        (ana/analyze-file f opts)))))
(defn current-file
  "Return the current file under analysis or compilation."
  []
  ana/*cljs-file*)
(defn warning-message
  "Helper for generating the standard analyzer messages for warnings. Should be\n  passed warn-type and warn-info. See with-warning-handlers."
  [warn-type warn-info]
  (ana/error-message warn-type warn-info))
(clojure.core/defn in-cljs-user
  "Binds cljs.analyzer/*cljs-ns* to 'cljs.user and uses the given compilation\n  environment atom and runs body."
  ([&form &env env & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote cljs.analyzer/*cljs-ns*))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote quote))
                      (clojure.core/list (quote cljs.user)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.env/with-compiler-env))
              (clojure.core/list env)
              body)))))))
(defn current-ns
  "Return the current ns under analysis or compilation."
  []
  ana/*cljs-ns*)
(defn all-ns
  "Return all namespaces. Analagous to clojure.core/all-ns but\n  returns symbols identifying namespaces not Namespace instances."
  ([] (all-ns env/*compiler*))
  ([state]
    (keys (get (clojure.core/deref state) :cljs.analyzer/namespaces))))
(clojure.core/defn with-warning-handlers
  "Helper macro for custom handling of emitted warnings. Handlers should be\n   a vector of functions. The signature of these functions is\n   [warn-type env warn-info]. warn-type is a keyword describing the warning,\n   env is the analysis environment, and warn-info is a map of extra useful\n   information for a particular warning type."
  ([&form &env handlers & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.analyzer/with-warning-handlers))
        (clojure.core/list handlers)
        body))))
(defn default-warning-handler
  "The default warning handler.\n\n   Outputs the warning messages to *err*."
  [warning-type env extra]
  (ana/default-warning-handler warning-type env extra))
(defn read-analysis-cache
  "Read an analysis cache."
  [cache-file]
  (case
    (util/ext cache-file)
    "edn"
    (edn/read-string (slurp cache-file))
    "json"
    (let [{:keys [reader read]} (clojure.core/deref ana/transit)]
      (with-open [is (io/input-stream cache-file)]
        (read (reader is :json ana/transit-read-opts))))))
cljs.pprint 394/481 (81.9%)
(clojure.core/defn setf
  "Set the value of the field SYM to NEW-VAL"
  ([&form &env sym new-val]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/swap!))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/deref))
              (clojure.core/list (quote this)))))
        (clojure.core/list (quote clojure.core/assoc))
        (clojure.core/list sym)
        (clojure.core/list new-val)))))
(clojure.core/defn formatter-out
  "Makes a function which can directly run format-in. The function is\nfn [& args] ... and returns nil. This version of the formatter macro is\ndesigned to be used with *out* set to an appropriate Writer. In particular,\nthis is meant to be used as part of a pretty printer dispatch method.\n\nformat-in can be either a control string or a previously compiled format."
  ([&form &env format-in]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote format-in__23288__auto__))
                (clojure.core/list format-in)
                (clojure.core/list (quote cf__23289__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote if))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/string?))
                            (clojure.core/list
                              (quote format-in__23288__auto__)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.pprint/cached-compile))
                            (clojure.core/list
                              (quote format-in__23288__auto__)))))
                      (clojure.core/list
                        (quote format-in__23288__auto__)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote &))
                      (clojure.core/list
                        (quote args__23290__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote navigator__23291__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.pprint/init-navigator))
                                  (clojure.core/list
                                    (quote args__23290__auto__)))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote cljs.pprint/execute-format))
                          (clojure.core/list (quote cf__23289__auto__))
                          (clojure.core/list
                            (quote
                              navigator__23291__auto__)))))))))))))))
(clojure.core/defn defdirectives
  ([&form &env & directives]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote def))
        (clojure.core/list (quote directive-table))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/hash-map))
              (mapcat process-directive-table-element directives))))))))
(defn- process-directive-table-element [[char
                                         params
                                         flags
                                         bracket-info
                                         &
                                         generator-fn]]
  [char
   {:directive char 
    :params
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/array-map))
        params)) 
    :flags flags 
    :bracket-info bracket-info 
    :generator-fn (concat (quote (fn [params offset])) generator-fn)}])
(clojure.core/defn pprint-logical-block
  "Execute the body as a pretty printing logical block with output to *out* which\n  must be a pretty printing writer. When used from pprint or cl-format, this can be\n  assumed.\n\n  This function is intended for use when writing custom dispatch functions.\n\n  Before the body, the caller can optionally specify options: :prefix, :per-line-prefix\n  and :suffix."
  ([&form &env & args]
    (let [[options body] (parse-lb-options
                           #{:suffix :prefix :per-line-prefix}
                           args)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote if))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list
                        (quote cljs.pprint/level-exceeded)))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote -write))
                      (clojure.core/list (quote cljs.core/*out*))
                      (clojure.core/list "#"))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote do))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.core/binding))
                            (clojure.core/list
                              (clojure.core/apply
                                clojure.core/vector
                                (clojure.core/seq
                                  (clojure.core/concat
                                    (clojure.core/list
                                      (quote
                                        cljs.pprint/*current-level*))
                                    (clojure.core/list
                                      (clojure.core/seq
                                        (clojure.core/concat
                                          (clojure.core/list
                                            (quote clojure.core/inc))
                                          (clojure.core/list
                                            (quote
                                              cljs.pprint/*current-level*)))))
                                    (clojure.core/list
                                      (quote
                                        cljs.pprint/*current-length*))
                                    (clojure.core/list 0)))))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.pprint/start-block))
                                  (clojure.core/list
                                    (quote cljs.core/*out*))
                                  (clojure.core/list (:prefix options))
                                  (clojure.core/list
                                    (:per-line-prefix options))
                                  (clojure.core/list
                                    (:suffix options)))))
                            body
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote cljs.pprint/end-block))
                                  (clojure.core/list
                                    (quote
                                      cljs.core/*out*))))))))))))))
          (clojure.core/list (quote nil)))))))
(clojure.core/defn print-length-loop
  "A version of loop that iterates at most *print-length* times. This is designed\n  for use in pretty-printer dispatch functions."
  ([&form &env bindings & body]
    (let [count-var (gensym "length-count")
          mod-body (pll-mod-body &env count-var body)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote clojure.core/loop))
          (clojure.core/list (apply vector count-var 0 bindings))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote if))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote clojure.core/or))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/not))
                            (clojure.core/list
                              (quote cljs.core/*print-length*)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote clojure.core/<))
                            (clojure.core/list count-var)
                            (clojure.core/list
                              (quote cljs.core/*print-length*))))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote do))
                      mod-body)))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote -write))
                      (clojure.core/list (quote cljs.core/*out*))
                      (clojure.core/list "..."))))))))))))
(clojure.core/defn with-pretty-writer
  ([&form &env base-writer & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote base-writer__23223__auto__))
                (clojure.core/list base-writer)
                (clojure.core/list (quote new-writer__23224__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote clojure.core/not))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote cljs.pprint/pretty-writer?))
                            (clojure.core/list
                              (quote
                                base-writer__23223__auto__))))))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote cljs.core/binding))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote cljs.core/*out*))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list (quote if))
                            (clojure.core/list
                              (quote new-writer__23224__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote
                                      cljs.pprint/make-pretty-writer))
                                  (clojure.core/list
                                    (quote base-writer__23223__auto__))
                                  (clojure.core/list
                                    (quote
                                      cljs.pprint/*print-right-margin*))
                                  (clojure.core/list
                                    (quote
                                      cljs.pprint/*print-miser-width*)))))
                            (clojure.core/list
                              (quote
                                base-writer__23223__auto__)))))))))
              body
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote cljs.pprint/-ppflush))
                    (clojure.core/list
                      (quote cljs.core/*out*))))))))))))
(defn- parse-lb-options [opts body]
  (loop [body body acc []]
    (if (opts (first body))
      (recur (drop 2 body) (concat acc (take 2 body)))
      [(apply hash-map acc) body])))
(clojure.core/defn getf
  "Get the value of the field a named by the argument (which should be a keyword)."
  ([&form &env sym]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list sym)
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/deref))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/deref))
                    (clojure.core/list (quote this))))))))))))
(clojure.core/defn deftype
  ([&form &env type-name & fields]
    (let [name-str (name type-name)
          fields (map (comp symbol name) fields)]
      (clojure.core/seq
        (clojure.core/concat
          (clojure.core/list (quote do))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote clojure.core/defrecord))
                (clojure.core/list type-name)
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list (quote type-tag))
                        fields)))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote clojure.core/defn-))
                (clojure.core/list (symbol (str "make-" name-str)))
                (clojure.core/list (vec fields))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (symbol (str type-name ".")))
                      (clojure.core/list (keyword name-str))
                      fields))))))
          (clojure.core/list
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote clojure.core/defn-))
                (clojure.core/list (symbol (str name-str "?")))
                (clojure.core/list
                  (clojure.core/apply
                    clojure.core/vector
                    (clojure.core/seq
                      (clojure.core/concat
                        (clojure.core/list
                          (quote x__23240__auto__))))))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote clojure.core/=))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list :type-tag)
                            (clojure.core/list
                              (quote x__23240__auto__)))))
                      (clojure.core/list (keyword name-str)))))))))))))
(defn- pll-mod-body [env var-sym body]
  (letfn
    [(inner
       [form]
       (if (seq? form)
         (let [form (macroexpand form)]
           (condp = (first form)
             (quote loop*) form
             (quote recur) (concat
                             (clojure.core/seq
                               (clojure.core/concat
                                 (clojure.core/list (quote recur))
                                 (clojure.core/list
                                   (clojure.core/seq
                                     (clojure.core/concat
                                       (clojure.core/list
                                         (quote clojure.core/inc))
                                       (clojure.core/list var-sym))))))
                             (rest form))
             (walk/walk inner identity form)))
         form))]
    (walk/walk inner identity body)))
(clojure.core/defn with-pprint-dispatch
  "Execute body with the pretty print dispatch function bound to function."
  ([&form &env function & body]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.core/binding))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list
                  (quote cljs.pprint/*print-pprint-dispatch*))
                (clojure.core/list function)))))
        body))))
(clojure.core/defn pp
  "A convenience macro that pretty prints the last thing output. This is\nexactly equivalent to (pprint *1)."
  {:added "1.2"}
  ([&form &env]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote cljs.pprint/pprint))
        (clojure.core/list (quote clojure.core/*1))))))
(clojure.core/defn formatter
  "Makes a function which can directly run format-in. The function is\nfn [stream & args] ... and returns nil unless the stream is nil (meaning\noutput to a string) in which case it returns the resulting string.\n\nformat-in can be either a control string or a previously compiled format."
  ([&form &env format-in]
    (clojure.core/seq
      (clojure.core/concat
        (clojure.core/list (quote clojure.core/let))
        (clojure.core/list
          (clojure.core/apply
            clojure.core/vector
            (clojure.core/seq
              (clojure.core/concat
                (clojure.core/list (quote format-in__23275__auto__))
                (clojure.core/list format-in)
                (clojure.core/list (quote my-c-c__23276__auto__))
                (clojure.core/list (quote cljs.pprint/cached-compile))
                (clojure.core/list (quote my-e-f__23277__auto__))
                (clojure.core/list (quote cljs.pprint/execute-format))
                (clojure.core/list (quote my-i-n__23278__auto__))
                (clojure.core/list (quote cljs.pprint/init-navigator))
                (clojure.core/list (quote cf__23279__auto__))
                (clojure.core/list
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote if))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote clojure.core/string?))
                            (clojure.core/list
                              (quote format-in__23275__auto__)))))
                      (clojure.core/list
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote my-c-c__23276__auto__))
                            (clojure.core/list
                              (quote format-in__23275__auto__)))))
                      (clojure.core/list
                        (quote format-in__23275__auto__)))))))))
        (clojure.core/list
          (clojure.core/seq
            (clojure.core/concat
              (clojure.core/list (quote clojure.core/fn))
              (clojure.core/list
                (clojure.core/apply
                  clojure.core/vector
                  (clojure.core/seq
                    (clojure.core/concat
                      (clojure.core/list (quote stream__23280__auto__))
                      (clojure.core/list (quote &))
                      (clojure.core/list
                        (quote args__23281__auto__))))))
              (clojure.core/list
                (clojure.core/seq
                  (clojure.core/concat
                    (clojure.core/list (quote clojure.core/let))
                    (clojure.core/list
                      (clojure.core/apply
                        clojure.core/vector
                        (clojure.core/seq
                          (clojure.core/concat
                            (clojure.core/list
                              (quote navigator__23282__auto__))
                            (clojure.core/list
                              (clojure.core/seq
                                (clojure.core/concat
                                  (clojure.core/list
                                    (quote my-i-n__23278__auto__))
                                  (clojure.core/list
                                    (quote args__23281__auto__)))))))))
                    (clojure.core/list
                      (clojure.core/seq
                        (clojure.core/concat
                          (clojure.core/list
                            (quote my-e-f__23277__auto__))
                          (clojure.core/list
                            (quote stream__23280__auto__))
                          (clojure.core/list (quote cf__23279__auto__))
                          (clojure.core/list
                            (quote
                              navigator__23282__auto__)))))))))))))))
cljs.externs-infer-tests 55/55 (100.0%)
(defn infer-test-helper [{:keys
                          [forms
                           externs
                           warnings
                           warn
                           js-dependency-index
                           with-core?
                           opts]}]
  (let [test-cenv (atom
                    (cond->
                      (if with-core?
                        (env/default-compiler-env*
                          (closure/add-externs-sources
                            (merge {:infer-externs true} opts)))
                        {:cljs.analyzer/externs(
                                        externs/externs-map(
                                          closure/load-externs{
                                            :externs(
                                             orexterns[] )}))})js-dependency-index      (assoc:js-dependency-index                js-dependency-index            )))wrap(ifwith-core?
                        (fn*[p1__15373#](comp/with-core-cljsnil p1__15373#
               ))(fn*[p1__15374# ](do(p1__15374#))))] (ana/with-warning-handlers      [(collecting-warning-handler(orwarnings    (atom[])))](binding[ana/*analyze-deps*falseana/*cljs-ns*ana/*cljs-ns*](env/with-compiler-env  test-cenv(wrap(fn[](binding[ ana/*analyze-deps*trueana/*cljs-warnings*  (assocana/*cljs-warnings*        :infer-warning      (if(nil?          warn)true            warn))]( ana/analyze-form-seqforms                        ))(with-out-str(comp/emit-externs                                        (reduceutil/map-merge                                             {}(map(comp:externs                                          second                                              )(get (clojure.core/deref                                   test-cenv                                            ):cljs.analyzer/namespaces))))))))))))